summaryrefslogtreecommitdiffstats
path: root/g4f/Provider
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--g4f/Provider/AI365VIP.py8
-rw-r--r--g4f/Provider/AIChatFree.py76
-rw-r--r--g4f/Provider/AIUncensored.py112
-rw-r--r--g4f/Provider/Ai4Chat.py88
-rw-r--r--g4f/Provider/AiChatOnline.py1
-rw-r--r--g4f/Provider/AiChats.py1
-rw-r--r--g4f/Provider/AiMathGPT.py74
-rw-r--r--g4f/Provider/Airforce.py380
-rw-r--r--g4f/Provider/Allyfy.py7
-rw-r--r--g4f/Provider/AmigoChat.py189
-rw-r--r--g4f/Provider/Aura.py4
-rw-r--r--g4f/Provider/Bing.py1
-rw-r--r--g4f/Provider/Binjie.py65
-rw-r--r--g4f/Provider/Bixin123.py94
-rw-r--r--g4f/Provider/Blackbox.py399
-rw-r--r--g4f/Provider/ChatGpt.py225
-rw-r--r--g4f/Provider/ChatGptEs.py84
-rw-r--r--g4f/Provider/ChatHub.py84
-rw-r--r--g4f/Provider/Chatgpt4Online.py6
-rw-r--r--g4f/Provider/Chatgpt4o.py9
-rw-r--r--g4f/Provider/ChatgptFree.py1
-rw-r--r--g4f/Provider/ChatifyAI.py79
-rw-r--r--g4f/Provider/Cloudflare.py212
-rw-r--r--g4f/Provider/CodeNews.py94
-rw-r--r--g4f/Provider/DDG.py162
-rw-r--r--g4f/Provider/DarkAI.py85
-rw-r--r--g4f/Provider/DeepInfraChat.py142
-rw-r--r--g4f/Provider/DeepInfraImage.py5
-rw-r--r--g4f/Provider/Editee.py77
-rw-r--r--g4f/Provider/FlowGpt.py3
-rw-r--r--g4f/Provider/FreeNetfly.py2
-rw-r--r--g4f/Provider/GPROChat.py67
-rw-r--r--g4f/Provider/GeminiPro.py8
-rw-r--r--g4f/Provider/GizAI.py151
-rw-r--r--g4f/Provider/GptTalkRu.py59
-rw-r--r--g4f/Provider/HuggingChat.py56
-rw-r--r--g4f/Provider/Koala.py1
-rw-r--r--g4f/Provider/Liaobots.py88
-rw-r--r--g4f/Provider/LiteIcoding.py113
-rw-r--r--g4f/Provider/MagickPen.py153
-rw-r--r--g4f/Provider/Nexra.py116
-rw-r--r--g4f/Provider/Ollama.py13
-rw-r--r--g4f/Provider/PerplexityLabs.py8
-rw-r--r--g4f/Provider/Pi.py1
-rw-r--r--g4f/Provider/Pizzagpt.py1
-rw-r--r--g4f/Provider/Prodia.py5
-rw-r--r--g4f/Provider/RubiksAI.py162
-rw-r--r--g4f/Provider/Snova.py131
-rw-r--r--g4f/Provider/TwitterBio.py103
-rw-r--r--g4f/Provider/Upstage.py7
-rw-r--r--g4f/Provider/Vercel.py104
-rw-r--r--g4f/Provider/You.py2
-rw-r--r--g4f/Provider/__init__.py37
-rw-r--r--g4f/Provider/gigachat/GigaChat.py (renamed from g4f/Provider/GigaChat.py)10
-rw-r--r--g4f/Provider/gigachat/__init__.py2
-rw-r--r--g4f/Provider/gigachat/russian_trusted_root_ca_pem.crt (renamed from g4f/Provider/gigachat_crt/russian_trusted_root_ca_pem.crt)0
-rw-r--r--g4f/Provider/needs_auth/Gemini.py3
-rw-r--r--g4f/Provider/needs_auth/Groq.py23
-rw-r--r--g4f/Provider/needs_auth/OpenRouter.py4
-rw-r--r--g4f/Provider/needs_auth/Openai.py2
-rw-r--r--g4f/Provider/needs_auth/OpenaiChat.py6
-rw-r--r--g4f/Provider/needs_auth/PerplexityApi.py3
-rw-r--r--g4f/Provider/needs_auth/__init__.py4
-rw-r--r--g4f/Provider/nexra/NexraBing.py93
-rw-r--r--g4f/Provider/nexra/NexraBlackbox.py100
-rw-r--r--g4f/Provider/nexra/NexraChatGPT.py285
-rw-r--r--g4f/Provider/nexra/NexraDallE.py63
-rw-r--r--g4f/Provider/nexra/NexraDallE2.py63
-rw-r--r--g4f/Provider/nexra/NexraEmi.py63
-rw-r--r--g4f/Provider/nexra/NexraFluxPro.py70
-rw-r--r--g4f/Provider/nexra/NexraGeminiPro.py86
-rw-r--r--g4f/Provider/nexra/NexraMidjourney.py63
-rw-r--r--g4f/Provider/nexra/NexraProdiaAI.py151
-rw-r--r--g4f/Provider/nexra/NexraQwen.py86
-rw-r--r--g4f/Provider/nexra/NexraSD15.py72
-rw-r--r--g4f/Provider/nexra/NexraSDLora.py69
-rw-r--r--g4f/Provider/nexra/NexraSDTurbo.py69
-rw-r--r--g4f/Provider/nexra/__init__.py14
-rw-r--r--g4f/Provider/openai/new.py730
-rw-r--r--g4f/Provider/selenium/Bard.py80
-rw-r--r--g4f/Provider/selenium/MyShell.py4
-rw-r--r--g4f/Provider/selenium/PerplexityAi.py4
-rw-r--r--g4f/Provider/selenium/TalkAi.py4
-rw-r--r--g4f/Provider/selenium/__init__.py1
-rw-r--r--g4f/Provider/unfinished/AiChatting.py66
-rw-r--r--g4f/Provider/unfinished/ChatAiGpt.py68
-rw-r--r--g4f/Provider/unfinished/Komo.py44
-rw-r--r--g4f/Provider/unfinished/MikuChat.py97
-rw-r--r--g4f/Provider/unfinished/__init__.py4
89 files changed, 4826 insertions, 1835 deletions
diff --git a/g4f/Provider/AI365VIP.py b/g4f/Provider/AI365VIP.py
index 2dcc8d1c..511ad568 100644
--- a/g4f/Provider/AI365VIP.py
+++ b/g4f/Provider/AI365VIP.py
@@ -10,17 +10,15 @@ from .helper import format_prompt
class AI365VIP(AsyncGeneratorProvider, ProviderModelMixin):
url = "https://chat.ai365vip.com"
api_endpoint = "/api/chat"
- working = True
- supports_gpt_35_turbo = True
- supports_gpt_4 = True
+ working = False
default_model = 'gpt-3.5-turbo'
models = [
'gpt-3.5-turbo',
+ 'gpt-3.5-turbo-16k',
'gpt-4o',
- 'claude-3-haiku-20240307',
]
model_aliases = {
- "claude-3-haiku": "claude-3-haiku-20240307",
+ "gpt-3.5-turbo": "gpt-3.5-turbo-16k",
}
@classmethod
diff --git a/g4f/Provider/AIChatFree.py b/g4f/Provider/AIChatFree.py
new file mode 100644
index 00000000..71c04681
--- /dev/null
+++ b/g4f/Provider/AIChatFree.py
@@ -0,0 +1,76 @@
+from __future__ import annotations
+
+import time
+from hashlib import sha256
+
+from aiohttp import BaseConnector, ClientSession
+
+from ..errors import RateLimitError
+from ..requests import raise_for_status
+from ..requests.aiohttp import get_connector
+from ..typing import AsyncResult, Messages
+from .base_provider import AsyncGeneratorProvider, ProviderModelMixin
+
+
+class AIChatFree(AsyncGeneratorProvider, ProviderModelMixin):
+ url = "https://aichatfree.info/"
+ working = True
+ supports_stream = True
+ supports_message_history = True
+ default_model = 'gemini-pro'
+
+ @classmethod
+ async def create_async_generator(
+ cls,
+ model: str,
+ messages: Messages,
+ proxy: str = None,
+ connector: BaseConnector = None,
+ **kwargs,
+ ) -> AsyncResult:
+ headers = {
+ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:122.0) Gecko/20100101 Firefox/122.0",
+ "Accept": "*/*",
+ "Accept-Language": "en-US,en;q=0.5",
+ "Accept-Encoding": "gzip, deflate, br",
+ "Content-Type": "text/plain;charset=UTF-8",
+ "Referer": f"{cls.url}/",
+ "Origin": cls.url,
+ "Sec-Fetch-Dest": "empty",
+ "Sec-Fetch-Mode": "cors",
+ "Sec-Fetch-Site": "same-origin",
+ "Connection": "keep-alive",
+ "TE": "trailers",
+ }
+ async with ClientSession(
+ connector=get_connector(connector, proxy), headers=headers
+ ) as session:
+ timestamp = int(time.time() * 1e3)
+ data = {
+ "messages": [
+ {
+ "role": "model" if message["role"] == "assistant" else "user",
+ "parts": [{"text": message["content"]}],
+ }
+ for message in messages
+ ],
+ "time": timestamp,
+ "pass": None,
+ "sign": generate_signature(timestamp, messages[-1]["content"]),
+ }
+ async with session.post(
+ f"{cls.url}/api/generate", json=data, proxy=proxy
+ ) as response:
+ if response.status == 500:
+ if "Quota exceeded" in await response.text():
+ raise RateLimitError(
+ f"Response {response.status}: Rate limit reached"
+ )
+ await raise_for_status(response)
+ async for chunk in response.content.iter_any():
+ yield chunk.decode(errors="ignore")
+
+
+def generate_signature(time: int, text: str, secret: str = ""):
+ message = f"{time}:{text}:{secret}"
+ return sha256(message.encode()).hexdigest()
diff --git a/g4f/Provider/AIUncensored.py b/g4f/Provider/AIUncensored.py
new file mode 100644
index 00000000..d653191c
--- /dev/null
+++ b/g4f/Provider/AIUncensored.py
@@ -0,0 +1,112 @@
+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
+from ..image import ImageResponse
+
+class AIUncensored(AsyncGeneratorProvider, ProviderModelMixin):
+ url = "https://www.aiuncensored.info"
+ working = True
+ supports_stream = True
+ supports_system_message = True
+ supports_message_history = True
+
+ default_model = 'ai_uncensored'
+ chat_models = [default_model]
+ image_models = ['ImageGenerator']
+ models = [*chat_models, *image_models]
+
+ api_endpoints = {
+ 'ai_uncensored': "https://twitterclone-i0wr.onrender.com/api/chat",
+ 'ImageGenerator': "https://twitterclone-4e8t.onrender.com/api/image"
+ }
+
+ @classmethod
+ def get_model(cls, model: str) -> str:
+ if model in cls.models:
+ return model
+ else:
+ return cls.default_model
+
+ @classmethod
+ async def create_async_generator(
+ cls,
+ model: str,
+ messages: Messages,
+ proxy: str = None,
+ stream: bool = False,
+ **kwargs
+ ) -> AsyncResult:
+ model = cls.get_model(model)
+
+ if model in cls.chat_models:
+ async with ClientSession(headers={"content-type": "application/json"}) as session:
+ data = {
+ "messages": [
+ {"role": "user", "content": format_prompt(messages)}
+ ],
+ "stream": stream
+ }
+ async with session.post(cls.api_endpoints[model], json=data, proxy=proxy) as response:
+ response.raise_for_status()
+ if stream:
+ async for chunk in cls._handle_streaming_response(response):
+ yield chunk
+ else:
+ yield await cls._handle_non_streaming_response(response)
+ elif model in cls.image_models:
+ headers = {
+ "accept": "*/*",
+ "accept-language": "en-US,en;q=0.9",
+ "cache-control": "no-cache",
+ "content-type": "application/json",
+ "origin": cls.url,
+ "pragma": "no-cache",
+ "priority": "u=1, i",
+ "referer": f"{cls.url}/",
+ "sec-ch-ua": '"Chromium";v="129", "Not=A?Brand";v="8"',
+ "sec-ch-ua-mobile": "?0",
+ "sec-ch-ua-platform": '"Linux"',
+ "sec-fetch-dest": "empty",
+ "sec-fetch-mode": "cors",
+ "sec-fetch-site": "cross-site",
+ "user-agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36"
+ }
+ async with ClientSession(headers=headers) as session:
+ prompt = messages[0]['content']
+ data = {"prompt": prompt}
+ async with session.post(cls.api_endpoints[model], json=data, proxy=proxy) as response:
+ response.raise_for_status()
+ result = await response.json()
+ image_url = result.get('image_url', '')
+ if image_url:
+ yield ImageResponse(image_url, alt=prompt)
+ else:
+ yield "Failed to generate image. Please try again."
+
+ @classmethod
+ async def _handle_streaming_response(cls, response):
+ async for line in response.content:
+ line = line.decode('utf-8').strip()
+ if line.startswith("data: "):
+ if line == "data: [DONE]":
+ break
+ try:
+ json_data = json.loads(line[6:])
+ if 'data' in json_data:
+ yield json_data['data']
+ except json.JSONDecodeError:
+ pass
+
+ @classmethod
+ async def _handle_non_streaming_response(cls, response):
+ response_json = await response.json()
+ return response_json.get('content', "Sorry, I couldn't generate a response.")
+
+ @classmethod
+ def validate_response(cls, response: str) -> str:
+ return response
diff --git a/g4f/Provider/Ai4Chat.py b/g4f/Provider/Ai4Chat.py
new file mode 100644
index 00000000..1096279d
--- /dev/null
+++ b/g4f/Provider/Ai4Chat.py
@@ -0,0 +1,88 @@
+from __future__ import annotations
+
+import json
+import re
+import logging
+from aiohttp import ClientSession
+
+from ..typing import AsyncResult, Messages
+from .base_provider import AsyncGeneratorProvider, ProviderModelMixin
+from .helper import format_prompt
+
+
+class Ai4Chat(AsyncGeneratorProvider, ProviderModelMixin):
+ label = "AI4Chat"
+ url = "https://www.ai4chat.co"
+ api_endpoint = "https://www.ai4chat.co/generate-response"
+ working = True
+ supports_stream = True
+ supports_system_message = True
+ supports_message_history = True
+
+ default_model = 'gpt-4'
+ models = [default_model]
+
+ model_aliases = {}
+
+ @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,
+ proxy: str = None,
+ **kwargs
+ ) -> AsyncResult:
+ model = cls.get_model(model)
+
+ headers = {
+ "accept": "*/*",
+ "accept-language": "en-US,en;q=0.9",
+ "cache-control": "no-cache",
+ "content-type": "application/json",
+ "origin": "https://www.ai4chat.co",
+ "pragma": "no-cache",
+ "priority": "u=1, i",
+ "referer": "https://www.ai4chat.co/gpt/talkdirtytome",
+ "sec-ch-ua": '"Chromium";v="129", "Not=A?Brand";v="8"',
+ "sec-ch-ua-mobile": "?0",
+ "sec-ch-ua-platform": '"Linux"',
+ "sec-fetch-dest": "empty",
+ "sec-fetch-mode": "cors",
+ "sec-fetch-site": "same-origin",
+ "user-agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36"
+ }
+
+ async with ClientSession(headers=headers) as session:
+ data = {
+ "messages": [
+ {
+ "role": "user",
+ "content": format_prompt(messages)
+ }
+ ]
+ }
+
+ try:
+ async with session.post(cls.api_endpoint, json=data, proxy=proxy) as response:
+ response.raise_for_status()
+ result = await response.text()
+
+ json_result = json.loads(result)
+
+ message = json_result.get("message", "")
+
+ clean_message = re.sub(r'<[^>]+>', '', message)
+
+ yield clean_message
+ except Exception as e:
+ logging.exception("Error while calling AI 4Chat API: %s", e)
+ yield f"Error: {e}"
diff --git a/g4f/Provider/AiChatOnline.py b/g4f/Provider/AiChatOnline.py
index 40f77105..26aacef6 100644
--- a/g4f/Provider/AiChatOnline.py
+++ b/g4f/Provider/AiChatOnline.py
@@ -12,7 +12,6 @@ class AiChatOnline(AsyncGeneratorProvider, ProviderModelMixin):
url = "https://aichatonlineorg.erweima.ai"
api_endpoint = "/aichatonline/api/chat/gpt"
working = True
- supports_gpt_4 = True
default_model = 'gpt-4o-mini'
@classmethod
diff --git a/g4f/Provider/AiChats.py b/g4f/Provider/AiChats.py
index 10127d4f..08492e24 100644
--- a/g4f/Provider/AiChats.py
+++ b/g4f/Provider/AiChats.py
@@ -12,7 +12,6 @@ class AiChats(AsyncGeneratorProvider, ProviderModelMixin):
url = "https://ai-chats.org"
api_endpoint = "https://ai-chats.org/chat/send2/"
working = True
- supports_gpt_4 = True
supports_message_history = True
default_model = 'gpt-4'
models = ['gpt-4', 'dalle']
diff --git a/g4f/Provider/AiMathGPT.py b/g4f/Provider/AiMathGPT.py
new file mode 100644
index 00000000..90931691
--- /dev/null
+++ b/g4f/Provider/AiMathGPT.py
@@ -0,0 +1,74 @@
+from __future__ import annotations
+
+from aiohttp import ClientSession
+
+from ..typing import AsyncResult, Messages
+from .base_provider import AsyncGeneratorProvider, ProviderModelMixin
+from .helper import format_prompt
+
+class AiMathGPT(AsyncGeneratorProvider, ProviderModelMixin):
+ url = "https://aimathgpt.forit.ai"
+ api_endpoint = "https://aimathgpt.forit.ai/api/ai"
+ working = True
+ supports_stream = False
+ supports_system_message = True
+ supports_message_history = True
+
+ default_model = 'llama3'
+ models = ['llama3']
+
+ model_aliases = {"llama-3.1-70b": "llama3",}
+
+ @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,
+ proxy: str = None,
+ **kwargs
+ ) -> AsyncResult:
+ model = cls.get_model(model)
+
+ headers = {
+ 'accept': '*/*',
+ 'accept-language': 'en-US,en;q=0.9',
+ 'cache-control': 'no-cache',
+ 'content-type': 'application/json',
+ 'origin': cls.url,
+ 'pragma': 'no-cache',
+ 'priority': 'u=1, i',
+ 'referer': f'{cls.url}/',
+ 'sec-ch-ua': '"Chromium";v="129", "Not=A?Brand";v="8"',
+ 'sec-ch-ua-mobile': '?0',
+ 'sec-ch-ua-platform': '"Linux"',
+ 'sec-fetch-dest': 'empty',
+ 'sec-fetch-mode': 'cors',
+ 'sec-fetch-site': 'same-origin',
+ 'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36'
+ }
+
+ async with ClientSession(headers=headers) as session:
+ data = {
+ "messages": [
+ {
+ "role": "user",
+ "content": format_prompt(messages)
+ }
+ ],
+ "model": model
+ }
+
+ async with session.post(cls.api_endpoint, json=data, proxy=proxy) as response:
+ response.raise_for_status()
+ response_data = await response.json()
+ filtered_response = response_data['result']['response']
+ yield filtered_response
diff --git a/g4f/Provider/Airforce.py b/g4f/Provider/Airforce.py
index 88896096..015766f4 100644
--- a/g4f/Provider/Airforce.py
+++ b/g4f/Provider/Airforce.py
@@ -1,94 +1,77 @@
from __future__ import annotations
-
-from aiohttp import ClientSession, ClientResponseError
-from urllib.parse import urlencode
+import random
import json
-import io
-import asyncio
-
+import re
+from aiohttp import ClientSession
from ..typing import AsyncResult, Messages
from .base_provider import AsyncGeneratorProvider, ProviderModelMixin
-from ..image import ImageResponse, is_accepted_format
-from .helper import format_prompt
+from ..image import ImageResponse
+
+def split_long_message(message: str, max_length: int = 4000) -> list[str]:
+ return [message[i:i+max_length] for i in range(0, len(message), max_length)]
class Airforce(AsyncGeneratorProvider, ProviderModelMixin):
url = "https://api.airforce"
+ image_api_endpoint = "https://api.airforce/imagine2"
text_api_endpoint = "https://api.airforce/chat/completions"
- image_api_endpoint = "https://api.airforce/v1/imagine2"
working = True
- supports_gpt_35_turbo = True
- supports_gpt_4 = True
+
+ default_model = 'llama-3-70b-chat'
+
supports_stream = True
supports_system_message = True
supports_message_history = True
- default_model = 'llama-3-70b-chat'
+
text_models = [
- # Open source models
- 'llama-2-13b-chat',
-
- 'llama-3-70b-chat',
- 'llama-3-70b-chat-turbo',
- 'llama-3-70b-chat-lite',
-
- 'llama-3-8b-chat',
- 'llama-3-8b-chat-turbo',
- 'llama-3-8b-chat-lite',
-
- 'llama-3.1-405b-turbo',
- 'llama-3.1-70b-turbo',
- 'llama-3.1-8b-turbo',
-
- 'LlamaGuard-2-8b',
- 'Llama-Guard-7b',
- 'Meta-Llama-Guard-3-8B',
-
- 'Mixtral-8x7B-Instruct-v0.1',
- 'Mixtral-8x22B-Instruct-v0.1',
- 'Mistral-7B-Instruct-v0.1',
- 'Mistral-7B-Instruct-v0.2',
- 'Mistral-7B-Instruct-v0.3',
-
- 'Qwen1.5-72B-Chat',
- 'Qwen1.5-110B-Chat',
- 'Qwen2-72B-Instruct',
-
- 'gemma-2b-it',
- 'gemma-2-9b-it',
- 'gemma-2-27b-it',
-
- 'dbrx-instruct',
-
- 'deepseek-llm-67b-chat',
-
- 'Nous-Hermes-2-Mixtral-8x7B-DPO',
- 'Nous-Hermes-2-Yi-34B',
-
- 'WizardLM-2-8x22B',
-
- 'SOLAR-10.7B-Instruct-v1.0',
-
- 'StripedHyena-Nous-7B',
-
- 'sparkdesk',
-
-
- # Other models
- 'chatgpt-4o-latest',
- 'gpt-4',
- 'gpt-4-turbo',
- 'gpt-4o-mini-2024-07-18',
- 'gpt-4o-mini',
- 'gpt-4o',
- 'gpt-3.5-turbo',
- 'gpt-3.5-turbo-0125',
- 'gpt-3.5-turbo-1106',
- 'gpt-3.5-turbo-16k',
- 'gpt-3.5-turbo-0613',
- 'gpt-3.5-turbo-16k-0613',
-
- 'gemini-1.5-flash',
- 'gemini-1.5-pro',
+ 'claude-3-haiku-20240307',
+ 'claude-3-sonnet-20240229',
+ 'claude-3-5-sonnet-20240620',
+ 'claude-3-opus-20240229',
+ 'chatgpt-4o-latest',
+ 'gpt-4',
+ 'gpt-4-turbo',
+ 'gpt-4o-mini-2024-07-18',
+ 'gpt-4o-mini',
+ 'gpt-3.5-turbo',
+ 'gpt-3.5-turbo-0125',
+ 'gpt-3.5-turbo-1106',
+ default_model,
+ 'llama-3-70b-chat-turbo',
+ 'llama-3-8b-chat',
+ 'llama-3-8b-chat-turbo',
+ 'llama-3-70b-chat-lite',
+ 'llama-3-8b-chat-lite',
+ 'llama-2-13b-chat',
+ 'llama-3.1-405b-turbo',
+ 'llama-3.1-70b-turbo',
+ 'llama-3.1-8b-turbo',
+ 'LlamaGuard-2-8b',
+ 'Llama-Guard-7b',
+ 'Llama-3.2-90B-Vision-Instruct-Turbo',
+ 'Mixtral-8x7B-Instruct-v0.1',
+ 'Mixtral-8x22B-Instruct-v0.1',
+ 'Mistral-7B-Instruct-v0.1',
+ 'Mistral-7B-Instruct-v0.2',
+ 'Mistral-7B-Instruct-v0.3',
+ 'Qwen1.5-7B-Chat',
+ 'Qwen1.5-14B-Chat',
+ 'Qwen1.5-72B-Chat',
+ 'Qwen1.5-110B-Chat',
+ 'Qwen2-72B-Instruct',
+ 'gemma-2b-it',
+ 'gemma-2-9b-it',
+ 'gemma-2-27b-it',
+ 'gemini-1.5-flash',
+ 'gemini-1.5-pro',
+ 'deepseek-llm-67b-chat',
+ 'Nous-Hermes-2-Mixtral-8x7B-DPO',
+ 'Nous-Hermes-2-Yi-34B',
+ 'WizardLM-2-8x22B',
+ 'SOLAR-10.7B-Instruct-v1.0',
+ 'MythoMax-L2-13b',
+ 'cosmosrp',
]
+
image_models = [
'flux',
'flux-realism',
@@ -96,160 +79,167 @@ class Airforce(AsyncGeneratorProvider, ProviderModelMixin):
'flux-3d',
'flux-disney',
'flux-pixel',
+ 'flux-4o',
'any-dark',
]
models = [
*text_models,
- *image_models
+ *image_models,
]
+
model_aliases = {
- # Open source models
- "llama-2-13b": "llama-2-13b-chat",
-
+ "claude-3-haiku": "claude-3-haiku-20240307",
+ "claude-3-sonnet": "claude-3-sonnet-20240229",
+ "gpt-4o": "chatgpt-4o-latest",
"llama-3-70b": "llama-3-70b-chat",
- "llama-3-70b": "llama-3-70b-chat-turbo",
- "llama-3-70b": "llama-3-70b-chat-lite",
-
"llama-3-8b": "llama-3-8b-chat",
- "llama-3-8b": "llama-3-8b-chat-turbo",
- "llama-3-8b": "llama-3-8b-chat-lite",
-
- "llama-3.1-405b": "llama-3.1-405b-turbo",
- "llama-3.1-70b": "llama-3.1-70b-turbo",
- "llama-3.1-8b": "llama-3.1-8b-turbo",
-
"mixtral-8x7b": "Mixtral-8x7B-Instruct-v0.1",
- "mixtral-8x22b": "Mixtral-8x22B-Instruct-v0.1",
- "mistral-7b": "Mistral-7B-Instruct-v0.1",
- "mistral-7b": "Mistral-7B-Instruct-v0.2",
- "mistral-7b": "Mistral-7B-Instruct-v0.3",
-
- "mixtral-8x7b-dpo": "Nous-Hermes-2-Mixtral-8x7B-DPO",
-
- "qwen-1-5-72b": "Qwen1.5-72B-Chat",
- "qwen-1_5-110b": "Qwen1.5-110B-Chat",
- "qwen-2-72b": "Qwen2-72B-Instruct",
-
+ "qwen-1.5-7b": "Qwen1.5-7B-Chat",
"gemma-2b": "gemma-2b-it",
- "gemma-2b-9b": "gemma-2-9b-it",
- "gemma-2b-27b": "gemma-2-27b-it",
-
- "deepseek": "deepseek-llm-67b-chat",
-
- "yi-34b": "Nous-Hermes-2-Yi-34B",
-
- "wizardlm-2-8x22b": "WizardLM-2-8x22B",
-
- "solar-10-7b": "SOLAR-10.7B-Instruct-v1.0",
-
- "sh-n-7b": "StripedHyena-Nous-7B",
-
- "sparkdesk-v1.1": "sparkdesk",
-
-
- # Other models
- "gpt-4o": "chatgpt-4o-latest",
- "gpt-4o-mini": "gpt-4o-mini-2024-07-18",
-
- "gpt-3.5-turbo": "gpt-3.5-turbo-0125",
- "gpt-3.5-turbo": "gpt-3.5-turbo-1106",
- "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",
-
-
"gemini-flash": "gemini-1.5-flash",
- "gemini-pro": "gemini-1.5-pro",
+ "mythomax-l2-13b": "MythoMax-L2-13b",
+ "solar-10.7b": "SOLAR-10.7B-Instruct-v1.0",
}
@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.get(model, cls.default_model)
+ else:
+ return cls.default_model
+
+ @classmethod
async def create_async_generator(
cls,
model: str,
messages: Messages,
proxy: str = None,
+ seed: int = None,
+ size: str = "1:1",
+ stream: bool = False,
**kwargs
) -> AsyncResult:
model = cls.get_model(model)
-
+
+ if model in cls.image_models:
+ async for result in cls._generate_image(model, messages, proxy, seed, size):
+ yield result
+ elif model in cls.text_models:
+ async for result in cls._generate_text(model, messages, proxy, stream):
+ yield result
+
+ @classmethod
+ async def _generate_image(
+ cls,
+ model: str,
+ messages: Messages,
+ proxy: str = None,
+ seed: int = None,
+ size: str = "1:1",
+ **kwargs
+ ) -> AsyncResult:
headers = {
"accept": "*/*",
"accept-language": "en-US,en;q=0.9",
- "content-type": "application/json",
- "origin": "https://api.airforce",
- "sec-ch-ua": '"Chromium";v="128", "Not(A:Brand";v="24"',
- "sec-ch-ua-mobile": "?0",
- "sec-ch-ua-platform": '"Linux"',
- "sec-fetch-dest": "empty",
- "sec-fetch-mode": "cors",
- "sec-fetch-site": "cross-site",
- "user-agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36"
+ "cache-control": "no-cache",
+ "origin": "https://llmplayground.net",
+ "user-agent": "Mozilla/5.0"
}
-
- if model in cls.image_models:
- async for item in cls.generate_image(model, messages, headers, proxy, **kwargs):
- yield item
- else:
- async for item in cls.generate_text(model, messages, headers, proxy, **kwargs):
- yield item
+ if seed is None:
+ seed = random.randint(0, 100000)
+
+ prompt = messages[-1]['content']
- @classmethod
- async def generate_text(cls, model: str, messages: Messages, headers: dict, proxy: str, **kwargs) -> AsyncResult:
async with ClientSession(headers=headers) as session:
- data = {
- "messages": [{"role": "user", "content": format_prompt(messages)}],
+ params = {
"model": model,
- "temperature": kwargs.get('temperature', 1),
- "top_p": kwargs.get('top_p', 1),
- "stream": True
+ "prompt": prompt,
+ "size": size,
+ "seed": seed
}
-
- async with session.post(cls.text_api_endpoint, json=data, proxy=proxy) as response:
+ async with session.get(f"{cls.image_api_endpoint}", params=params, proxy=proxy) as response:
response.raise_for_status()
- async for line in response.content:
- if line:
- line = line.decode('utf-8').strip()
- if line.startswith("data: "):
- try:
- data = json.loads(line[6:])
- if 'choices' in data and len(data['choices']) > 0:
- delta = data['choices'][0].get('delta', {})
- if 'content' in delta:
- yield delta['content']
- except json.JSONDecodeError:
- continue
- elif line == "data: [DONE]":
- break
+ content_type = response.headers.get('Content-Type', '').lower()
+
+ if 'application/json' in content_type:
+ async for chunk in response.content.iter_chunked(1024):
+ if chunk:
+ yield chunk.decode('utf-8')
+ elif 'image' in content_type:
+ image_data = b""
+ async for chunk in response.content.iter_chunked(1024):
+ if chunk:
+ image_data += chunk
+ image_url = f"{cls.image_api_endpoint}?model={model}&prompt={prompt}&size={size}&seed={seed}"
+ alt_text = f"Generated image for prompt: {prompt}"
+ yield ImageResponse(images=image_url, alt=alt_text)
@classmethod
- async def generate_image(cls, model: str, messages: Messages, headers: dict, proxy: str, **kwargs) -> AsyncResult:
- prompt = messages[-1]['content'] if messages else ""
- params = {
- "prompt": prompt,
- "size": kwargs.get("size", "1:1"),
- "seed": kwargs.get("seed"),
- "model": model
+ async def _generate_text(
+ cls,
+ model: str,
+ messages: Messages,
+ proxy: str = None,
+ stream: bool = False,
+ **kwargs
+ ) -> AsyncResult:
+ headers = {
+ "accept": "*/*",
+ "accept-language": "en-US,en;q=0.9",
+ "authorization": "Bearer missing api key",
+ "content-type": "application/json",
+ "user-agent": "Mozilla/5.0"
}
- params = {k: v for k, v in params.items() if v is not None}
- try:
- async with ClientSession(headers=headers) as session:
- async with session.get(cls.image_api_endpoint, params=params, proxy=proxy) as response:
+ async with ClientSession(headers=headers) as session:
+ formatted_prompt = cls._format_messages(messages)
+ prompt_parts = split_long_message(formatted_prompt)
+ full_response = ""
+
+ for part in prompt_parts:
+ data = {
+ "messages": [{"role": "user", "content": part}],
+ "model": model,
+ "max_tokens": 4096,
+ "temperature": 1,
+ "top_p": 1,
+ "stream": stream
+ }
+ async with session.post(cls.text_api_endpoint, json=data, proxy=proxy) as response:
response.raise_for_status()
- content = await response.read()
-
- if response.content_type.startswith('image/'):
- image_url = str(response.url)
- yield ImageResponse(image_url, prompt)
+ part_response = ""
+ if stream:
+ async for line in response.content:
+ if line:
+ line = line.decode('utf-8').strip()
+ if line.startswith("data: ") and line != "data: [DONE]":
+ json_data = json.loads(line[6:])
+ content = json_data['choices'][0]['delta'].get('content', '')
+ part_response += content
else:
- try:
- text = content.decode('utf-8', errors='ignore')
- yield f"Error: {text}"
- except Exception as decode_error:
- yield f"Error: Unable to decode response - {str(decode_error)}"
- except ClientResponseError as e:
- yield f"Error: HTTP {e.status}: {e.message}"
- except Exception as e:
- yield f"Unexpected error: {str(e)}"
+ json_data = await response.json()
+ content = json_data['choices'][0]['message']['content']
+ part_response = content
+
+ part_response = re.sub(
+ r"One message exceeds the \d+chars per message limit\..+https:\/\/discord\.com\/invite\/\S+",
+ '',
+ part_response
+ )
+
+ part_response = re.sub(
+ r"Rate limit \(\d+\/minute\) exceeded\. Join our discord for more: .+https:\/\/discord\.com\/invite\/\S+",
+ '',
+ part_response
+ )
+
+ full_response += part_response
+ yield full_response
+
+ @classmethod
+ def _format_messages(cls, messages: Messages) -> str:
+ return " ".join([msg['content'] for msg in messages])
diff --git a/g4f/Provider/Allyfy.py b/g4f/Provider/Allyfy.py
index 8733b1ec..bf607df4 100644
--- a/g4f/Provider/Allyfy.py
+++ b/g4f/Provider/Allyfy.py
@@ -9,10 +9,9 @@ from .helper import format_prompt
class Allyfy(AsyncGeneratorProvider):
- url = "https://chatbot.allyfy.chat"
- api_endpoint = "/api/v1/message/stream/super/chat"
+ url = "https://allyfy.chat"
+ api_endpoint = "https://chatbot.allyfy.chat/api/v1/message/stream/super/chat"
working = True
- supports_gpt_35_turbo = True
@classmethod
async def create_async_generator(
@@ -53,7 +52,7 @@ class Allyfy(AsyncGeneratorProvider):
"packageName": "com.cch.allyfy.webh",
}
}
- async with session.post(f"{cls.url}{cls.api_endpoint}", json=data, proxy=proxy) as response:
+ async with session.post(f"{cls.api_endpoint}", json=data, proxy=proxy) as response:
response.raise_for_status()
full_response = []
async for line in response.content:
diff --git a/g4f/Provider/AmigoChat.py b/g4f/Provider/AmigoChat.py
new file mode 100644
index 00000000..f5027111
--- /dev/null
+++ b/g4f/Provider/AmigoChat.py
@@ -0,0 +1,189 @@
+from __future__ import annotations
+
+import json
+import uuid
+from aiohttp import ClientSession, ClientTimeout, ClientResponseError
+
+from ..typing import AsyncResult, Messages
+from .base_provider import AsyncGeneratorProvider, ProviderModelMixin
+from .helper import format_prompt
+from ..image import ImageResponse
+
+class AmigoChat(AsyncGeneratorProvider, ProviderModelMixin):
+ url = "https://amigochat.io/chat/"
+ chat_api_endpoint = "https://api.amigochat.io/v1/chat/completions"
+ image_api_endpoint = "https://api.amigochat.io/v1/images/generations"
+ working = True
+ supports_stream = True
+ supports_system_message = True
+ supports_message_history = True
+
+ default_model = 'gpt-4o-mini'
+
+ chat_models = [
+ 'gpt-4o',
+ default_model,
+ 'o1-preview',
+ 'o1-mini',
+ 'meta-llama/Meta-Llama-3.1-405B-Instruct-Turbo',
+ 'meta-llama/Llama-3.2-90B-Vision-Instruct-Turbo',
+ 'claude-3-sonnet-20240229',
+ 'gemini-1.5-pro',
+ ]
+
+ image_models = [
+ 'flux-pro/v1.1',
+ 'flux-realism',
+ 'flux-pro',
+ 'dalle-e-3',
+ ]
+
+ models = [*chat_models, *image_models]
+
+ model_aliases = {
+ "o1": "o1-preview",
+ "llama-3.1-405b": "meta-llama/Meta-Llama-3.1-405B-Instruct-Turbo",
+ "llama-3.2-90b": "meta-llama/Llama-3.2-90B-Vision-Instruct-Turbo",
+ "claude-3.5-sonnet": "claude-3-sonnet-20240229",
+ "gemini-pro": "gemini-1.5-pro",
+
+ "flux-pro": "flux-pro/v1.1",
+ "dalle-3": "dalle-e-3",
+ }
+
+ persona_ids = {
+ 'gpt-4o': "gpt",
+ 'gpt-4o-mini': "amigo",
+ 'o1-preview': "openai-o-one",
+ 'o1-mini': "openai-o-one-mini",
+ 'meta-llama/Meta-Llama-3.1-405B-Instruct-Turbo': "llama-three-point-one",
+ 'meta-llama/Llama-3.2-90B-Vision-Instruct-Turbo': "llama-3-2",
+ 'claude-3-sonnet-20240229': "claude",
+ 'gemini-1.5-pro': "gemini-1-5-pro",
+ 'flux-pro/v1.1': "flux-1-1-pro",
+ 'flux-realism': "flux-realism",
+ 'flux-pro': "flux-pro",
+ 'dalle-e-3': "dalle-three",
+ }
+
+ @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 get_personaId(cls, model: str) -> str:
+ return cls.persona_ids[model]
+
+ @classmethod
+ async def create_async_generator(
+ cls,
+ model: str,
+ messages: Messages,
+ proxy: str = None,
+ stream: bool = False,
+ **kwargs
+ ) -> AsyncResult:
+ model = cls.get_model(model)
+
+ device_uuid = str(uuid.uuid4())
+ max_retries = 3
+ retry_count = 0
+
+ while retry_count < max_retries:
+ try:
+ headers = {
+ "accept": "*/*",
+ "accept-language": "en-US,en;q=0.9",
+ "authorization": "Bearer",
+ "cache-control": "no-cache",
+ "content-type": "application/json",
+ "origin": cls.url,
+ "pragma": "no-cache",
+ "priority": "u=1, i",
+ "referer": f"{cls.url}/",
+ "sec-ch-ua": '"Chromium";v="129", "Not=A?Brand";v="8"',
+ "sec-ch-ua-mobile": "?0",
+ "sec-ch-ua-platform": '"Linux"',
+ "user-agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36",
+ "x-device-language": "en-US",
+ "x-device-platform": "web",
+ "x-device-uuid": device_uuid,
+ "x-device-version": "1.0.32"
+ }
+
+ async with ClientSession(headers=headers) as session:
+ if model in cls.chat_models:
+ # Chat completion
+ data = {
+ "messages": [{"role": m["role"], "content": m["content"]} for m in messages],
+ "model": model,
+ "personaId": cls.get_personaId(model),
+ "frequency_penalty": 0,
+ "max_tokens": 4000,
+ "presence_penalty": 0,
+ "stream": stream,
+ "temperature": 0.5,
+ "top_p": 0.95
+ }
+
+ timeout = ClientTimeout(total=300) # 5 minutes timeout
+ async with session.post(cls.chat_api_endpoint, json=data, proxy=proxy, timeout=timeout) as response:
+ if response.status not in (200, 201):
+ error_text = await response.text()
+ raise Exception(f"Error {response.status}: {error_text}")
+
+ async for line in response.content:
+ line = line.decode('utf-8').strip()
+ if line.startswith('data: '):
+ if line == 'data: [DONE]':
+ break
+ try:
+ chunk = json.loads(line[6:]) # Remove 'data: ' prefix
+ if 'choices' in chunk and len(chunk['choices']) > 0:
+ choice = chunk['choices'][0]
+ if 'delta' in choice:
+ content = choice['delta'].get('content')
+ elif 'text' in choice:
+ content = choice['text']
+ else:
+ content = None
+ if content:
+ yield content
+ except json.JSONDecodeError:
+ pass
+ else:
+ # Image generation
+ prompt = messages[-1]['content']
+ data = {
+ "prompt": prompt,
+ "model": model,
+ "personaId": cls.get_personaId(model)
+ }
+ async with session.post(cls.image_api_endpoint, json=data, proxy=proxy) as response:
+ response.raise_for_status()
+
+ response_data = await response.json()
+
+ if "data" in response_data:
+ image_urls = []
+ for item in response_data["data"]:
+ if "url" in item:
+ image_url = item["url"]
+ image_urls.append(image_url)
+ if image_urls:
+ yield ImageResponse(image_urls, prompt)
+ else:
+ yield None
+
+ break
+
+ except (ClientResponseError, Exception) as e:
+ retry_count += 1
+ if retry_count >= max_retries:
+ raise e
+ device_uuid = str(uuid.uuid4())
diff --git a/g4f/Provider/Aura.py b/g4f/Provider/Aura.py
index 4a8d0a55..e2c56754 100644
--- a/g4f/Provider/Aura.py
+++ b/g4f/Provider/Aura.py
@@ -9,7 +9,7 @@ from ..webdriver import WebDriver
class Aura(AsyncGeneratorProvider):
url = "https://openchat.team"
- working = True
+ working = False
@classmethod
async def create_async_generator(
@@ -46,4 +46,4 @@ class Aura(AsyncGeneratorProvider):
async with session.post(f"{cls.url}/api/chat", json=data, proxy=proxy) as response:
response.raise_for_status()
async for chunk in response.content.iter_any():
- yield chunk.decode(error="ignore") \ No newline at end of file
+ yield chunk.decode(error="ignore")
diff --git a/g4f/Provider/Bing.py b/g4f/Provider/Bing.py
index 4056f9ff..f04b1a54 100644
--- a/g4f/Provider/Bing.py
+++ b/g4f/Provider/Bing.py
@@ -37,7 +37,6 @@ class Bing(AsyncGeneratorProvider, ProviderModelMixin):
url = "https://bing.com/chat"
working = True
supports_message_history = True
- supports_gpt_4 = True
default_model = "Balanced"
default_vision_model = "gpt-4-vision"
models = [getattr(Tones, key) for key in Tones.__dict__ if not key.startswith("__")]
diff --git a/g4f/Provider/Binjie.py b/g4f/Provider/Binjie.py
deleted file mode 100644
index 90f9ec3c..00000000
--- a/g4f/Provider/Binjie.py
+++ /dev/null
@@ -1,65 +0,0 @@
-from __future__ import annotations
-
-import random
-from ..requests import StreamSession
-
-from ..typing import AsyncResult, Messages
-from .base_provider import AsyncGeneratorProvider, format_prompt
-
-
-class Binjie(AsyncGeneratorProvider):
- url = "https://chat18.aichatos8.com"
- working = True
- supports_gpt_4 = True
- supports_stream = True
- supports_system_message = True
- supports_message_history = True
-
- @staticmethod
- async def create_async_generator(
- model: str,
- messages: Messages,
- proxy: str = None,
- timeout: int = 120,
- **kwargs,
- ) -> AsyncResult:
- async with StreamSession(
- headers=_create_header(), proxies={"https": proxy}, timeout=timeout
- ) as session:
- payload = _create_payload(messages, **kwargs)
- async with session.post("https://api.binjie.fun/api/generateStream", json=payload) as response:
- response.raise_for_status()
- async for chunk in response.iter_content():
- if chunk:
- chunk = chunk.decode()
- if "sorry, 您的ip已由于触发防滥用检测而被封禁" in chunk:
- raise RuntimeError("IP address is blocked by abuse detection.")
- yield chunk
-
-
-def _create_header():
- return {
- "accept" : "application/json, text/plain, */*",
- "content-type" : "application/json",
- "origin" : "https://chat18.aichatos8.com",
- "referer" : "https://chat18.aichatos8.com/"
- }
-
-
-def _create_payload(
- messages: Messages,
- system_message: str = "",
- user_id: int = None,
- **kwargs
-):
- if not user_id:
- user_id = random.randint(1690000544336, 2093025544336)
- return {
- "prompt": format_prompt(messages),
- "network": True,
- "system": system_message,
- "withoutContext": False,
- "stream": True,
- "userId": f"#/chat/{user_id}"
- }
-
diff --git a/g4f/Provider/Bixin123.py b/g4f/Provider/Bixin123.py
deleted file mode 100644
index 39422c93..00000000
--- a/g4f/Provider/Bixin123.py
+++ /dev/null
@@ -1,94 +0,0 @@
-from __future__ import annotations
-
-from aiohttp import ClientSession
-import json
-import random
-from .base_provider import AsyncGeneratorProvider, ProviderModelMixin
-from ..typing import AsyncResult, Messages
-from .helper import format_prompt
-
-class Bixin123(AsyncGeneratorProvider, ProviderModelMixin):
- url = "https://chat.bixin123.com"
- api_endpoint = "https://chat.bixin123.com/api/chatgpt/chat-process"
- working = True
- supports_gpt_35_turbo = True
- supports_gpt_4 = True
-
- default_model = 'gpt-3.5-turbo-0125'
- models = ['gpt-3.5-turbo-0125', 'gpt-3.5-turbo-16k-0613', 'gpt-4-turbo', 'qwen-turbo']
-
- model_aliases = {
- "gpt-3.5-turbo": "gpt-3.5-turbo-0125",
- "gpt-3.5-turbo": "gpt-3.5-turbo-16k-0613",
- }
-
- @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 generate_fingerprint(cls) -> str:
- return str(random.randint(100000000, 999999999))
-
- @classmethod
- async def create_async_generator(
- cls,
- model: str,
- messages: Messages,
- proxy: str = None,
- **kwargs
- ) -> AsyncResult:
- model = cls.get_model(model)
-
- headers = {
- "accept": "application/json, text/plain, */*",
- "accept-language": "en-US,en;q=0.9",
- "cache-control": "no-cache",
- "content-type": "application/json",
- "fingerprint": cls.generate_fingerprint(),
- "origin": cls.url,
- "pragma": "no-cache",
- "priority": "u=1, i",
- "referer": f"{cls.url}/chat",
- "sec-ch-ua": '"Chromium";v="127", "Not)A;Brand";v="99"',
- "sec-ch-ua-mobile": "?0",
- "sec-ch-ua-platform": '"Linux"',
- "sec-fetch-dest": "empty",
- "sec-fetch-mode": "cors",
- "sec-fetch-site": "same-origin",
- "user-agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36",
- "x-website-domain": "chat.bixin123.com",
- }
-
- async with ClientSession(headers=headers) as session:
- prompt = format_prompt(messages)
- data = {
- "prompt": prompt,
- "options": {
- "usingNetwork": False,
- "file": ""
- }
- }
- async with session.post(cls.api_endpoint, json=data, proxy=proxy) as response:
- response.raise_for_status()
- response_text = await response.text()
-
- lines = response_text.strip().split("\n")
- last_json = None
- for line in reversed(lines):
- try:
- last_json = json.loads(line)
- break
- except json.JSONDecodeError:
- pass
-
- if last_json:
- text = last_json.get("text", "")
- yield text
- else:
- yield ""
diff --git a/g4f/Provider/Blackbox.py b/g4f/Provider/Blackbox.py
index e607a43c..4052893a 100644
--- a/g4f/Provider/Blackbox.py
+++ b/g4f/Provider/Blackbox.py
@@ -1,40 +1,122 @@
from __future__ import annotations
-import re
-import json
+import asyncio
+import aiohttp
import random
import string
-from aiohttp import ClientSession
+import json
+import uuid
+import re
+from typing import Optional, AsyncGenerator, Union
+
+from aiohttp import ClientSession, ClientResponseError
from ..typing import AsyncResult, Messages, ImageType
-from ..image import ImageResponse, to_data_uri
from .base_provider import AsyncGeneratorProvider, ProviderModelMixin
+from ..image import ImageResponse, to_data_uri
+
class Blackbox(AsyncGeneratorProvider, ProviderModelMixin):
+ label = "Blackbox AI"
url = "https://www.blackbox.ai"
api_endpoint = "https://www.blackbox.ai/api/chat"
working = True
supports_stream = True
supports_system_message = True
supports_message_history = True
-
- default_model = 'blackbox'
+
+ default_model = 'blackboxai'
+ image_models = ['ImageGeneration']
models = [
- 'blackbox',
- 'gemini-1.5-flash',
+ default_model,
+ 'blackboxai-pro',
+ *image_models,
"llama-3.1-8b",
'llama-3.1-70b',
'llama-3.1-405b',
- 'ImageGenerationLV45LJp'
+ 'gpt-4o',
+ 'gemini-pro',
+ 'gemini-1.5-flash',
+ 'claude-sonnet-3.5',
+ 'PythonAgent',
+ 'JavaAgent',
+ 'JavaScriptAgent',
+ 'HTMLAgent',
+ 'GoogleCloudAgent',
+ 'AndroidDeveloper',
+ 'SwiftDeveloper',
+ 'Next.jsAgent',
+ 'MongoDBAgent',
+ 'PyTorchAgent',
+ 'ReactAgent',
+ 'XcodeAgent',
+ 'AngularJSAgent',
]
- model_config = {
- "blackbox": {},
+ agentMode = {
+ 'ImageGeneration': {'mode': True, 'id': "ImageGenerationLV45LJp", 'name': "Image Generation"},
+ }
+
+ trendingAgentMode = {
+ "blackboxai": {},
"gemini-1.5-flash": {'mode': True, 'id': 'Gemini'},
"llama-3.1-8b": {'mode': True, 'id': "llama-3.1-8b"},
'llama-3.1-70b': {'mode': True, 'id': "llama-3.1-70b"},
'llama-3.1-405b': {'mode': True, 'id': "llama-3.1-405b"},
- 'ImageGenerationLV45LJp': {'mode': True, 'id': "ImageGenerationLV45LJp", 'name': "Image Generation"},
+ 'blackboxai-pro': {'mode': True, 'id': "BLACKBOXAI-PRO"},
+ 'PythonAgent': {'mode': True, 'id': "Python Agent"},
+ 'JavaAgent': {'mode': True, 'id': "Java Agent"},
+ 'JavaScriptAgent': {'mode': True, 'id': "JavaScript Agent"},
+ 'HTMLAgent': {'mode': True, 'id': "HTML Agent"},
+ 'GoogleCloudAgent': {'mode': True, 'id': "Google Cloud Agent"},
+ 'AndroidDeveloper': {'mode': True, 'id': "Android Developer"},
+ 'SwiftDeveloper': {'mode': True, 'id': "Swift Developer"},
+ 'Next.jsAgent': {'mode': True, 'id': "Next.js Agent"},
+ 'MongoDBAgent': {'mode': True, 'id': "MongoDB Agent"},
+ 'PyTorchAgent': {'mode': True, 'id': "PyTorch Agent"},
+ 'ReactAgent': {'mode': True, 'id': "React Agent"},
+ 'XcodeAgent': {'mode': True, 'id': "Xcode Agent"},
+ 'AngularJSAgent': {'mode': True, 'id': "AngularJS Agent"},
+ }
+
+ userSelectedModel = {
+ "gpt-4o": "gpt-4o",
+ "gemini-pro": "gemini-pro",
+ 'claude-sonnet-3.5': "claude-sonnet-3.5",
+ }
+
+ model_prefixes = {
+ 'gpt-4o': '@GPT-4o',
+ 'gemini-pro': '@Gemini-PRO',
+ 'claude-sonnet-3.5': '@Claude-Sonnet-3.5',
+ 'PythonAgent': '@Python Agent',
+ 'JavaAgent': '@Java Agent',
+ 'JavaScriptAgent': '@JavaScript Agent',
+ 'HTMLAgent': '@HTML Agent',
+ 'GoogleCloudAgent': '@Google Cloud Agent',
+ 'AndroidDeveloper': '@Android Developer',
+ 'SwiftDeveloper': '@Swift Developer',
+ 'Next.jsAgent': '@Next.js Agent',
+ 'MongoDBAgent': '@MongoDB Agent',
+ 'PyTorchAgent': '@PyTorch Agent',
+ 'ReactAgent': '@React Agent',
+ 'XcodeAgent': '@Xcode Agent',
+ 'AngularJSAgent': '@AngularJS Agent',
+ 'blackboxai-pro': '@BLACKBOXAI-PRO',
+ 'ImageGeneration': '@Image Generation',
+ }
+
+ model_referers = {
+ "blackboxai": "/?model=blackboxai",
+ "gpt-4o": "/?model=gpt-4o",
+ "gemini-pro": "/?model=gemini-pro",
+ "claude-sonnet-3.5": "/?model=claude-sonnet-3.5"
+ }
+
+ model_aliases = {
+ "gemini-flash": "gemini-1.5-flash",
+ "claude-3.5-sonnet": "claude-sonnet-3.5",
+ "flux": "ImageGeneration",
}
@classmethod
@@ -46,82 +128,245 @@ class Blackbox(AsyncGeneratorProvider, ProviderModelMixin):
else:
return cls.default_model
+ @staticmethod
+ def generate_random_string(length: int = 7) -> str:
+ characters = string.ascii_letters + string.digits
+ return ''.join(random.choices(characters, k=length))
+
+ @staticmethod
+ def generate_next_action() -> str:
+ return uuid.uuid4().hex
+
+ @staticmethod
+ def generate_next_router_state_tree() -> str:
+ router_state = [
+ "",
+ {
+ "children": [
+ "(chat)",
+ {
+ "children": [
+ "__PAGE__",
+ {}
+ ]
+ }
+ ]
+ },
+ None,
+ None,
+ True
+ ]
+ return json.dumps(router_state)
+
+ @staticmethod
+ def clean_response(text: str) -> str:
+ pattern = r'^\$\@\$v=undefined-rv1\$\@\$'
+ cleaned_text = re.sub(pattern, '', text)
+ return cleaned_text
+
@classmethod
async def create_async_generator(
cls,
model: str,
messages: Messages,
- proxy: str = None,
+ proxy: Optional[str] = None,
image: ImageType = None,
image_name: str = None,
+ web_search: bool = False,
**kwargs
- ) -> AsyncResult:
+ ) -> AsyncGenerator[Union[str, ImageResponse], None]:
+ """
+ Creates an asynchronous generator for streaming responses from Blackbox AI.
+
+ Parameters:
+ model (str): Model to use for generating responses.
+ messages (Messages): Message history.
+ proxy (Optional[str]): Proxy URL, if needed.
+ image (ImageType): Image data to be processed, if any.
+ image_name (str): Name of the image file, if an image is provided.
+ web_search (bool): Enables or disables web search mode.
+ **kwargs: Additional keyword arguments.
+
+ Yields:
+ Union[str, ImageResponse]: Segments of the generated response or ImageResponse objects.
+ """
+
+ if image is not None:
+ messages[-1]['data'] = {
+ 'fileText': '',
+ 'imageBase64': to_data_uri(image),
+ 'title': image_name
+ }
+ messages[-1]['content'] = 'FILE:BB\n$#$\n\n$#$\n' + messages[-1]['content']
+
model = cls.get_model(model)
+
+ chat_id = cls.generate_random_string()
+ next_action = cls.generate_next_action()
+ next_router_state_tree = cls.generate_next_router_state_tree()
+
+ agent_mode = cls.agentMode.get(model, {})
+ trending_agent_mode = cls.trendingAgentMode.get(model, {})
+
+ prefix = cls.model_prefixes.get(model, "")
- headers = {
- "accept": "*/*",
- "accept-language": "en-US,en;q=0.9",
- "cache-control": "no-cache",
- "content-type": "application/json",
- "origin": cls.url,
- "pragma": "no-cache",
- "referer": f"{cls.url}/",
- "sec-ch-ua": '"Not;A=Brand";v="24", "Chromium";v="128"',
- "sec-ch-ua-mobile": "?0",
- "sec-ch-ua-platform": '"Linux"',
- "sec-fetch-dest": "empty",
- "sec-fetch-mode": "cors",
- "sec-fetch-site": "same-origin",
- "user-agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36"
- }
+ formatted_prompt = ""
+ for message in messages:
+ role = message.get('role', '').capitalize()
+ content = message.get('content', '')
+ if role and content:
+ formatted_prompt += f"{role}: {content}\n"
- async with ClientSession(headers=headers) as session:
- if image is not None:
- messages[-1]["data"] = {
- "fileText": image_name,
- "imageBase64": to_data_uri(image)
+ if prefix:
+ formatted_prompt = f"{prefix} {formatted_prompt}".strip()
+
+ referer_path = cls.model_referers.get(model, f"/?model={model}")
+ referer_url = f"{cls.url}{referer_path}"
+
+ common_headers = {
+ 'accept': '*/*',
+ 'accept-language': 'en-US,en;q=0.9',
+ 'cache-control': 'no-cache',
+ 'origin': cls.url,
+ 'pragma': 'no-cache',
+ 'priority': 'u=1, i',
+ 'sec-ch-ua': '"Chromium";v="129", "Not=A?Brand";v="8"',
+ 'sec-ch-ua-mobile': '?0',
+ 'sec-ch-ua-platform': '"Linux"',
+ 'sec-fetch-dest': 'empty',
+ 'sec-fetch-mode': 'cors',
+ 'sec-fetch-site': 'same-origin',
+ 'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) '
+ 'AppleWebKit/537.36 (KHTML, like Gecko) '
+ 'Chrome/129.0.0.0 Safari/537.36'
+ }
+
+ headers_api_chat = {
+ 'Content-Type': 'application/json',
+ 'Referer': referer_url
+ }
+ headers_api_chat_combined = {**common_headers, **headers_api_chat}
+
+ payload_api_chat = {
+ "messages": [
+ {
+ "id": chat_id,
+ "content": formatted_prompt,
+ "role": "user",
+ "data": messages[-1].get('data')
}
-
- random_id = ''.join(random.choices(string.ascii_letters + string.digits, k=7))
-
- data = {
- "messages": messages,
- "id": random_id,
- "previewToken": None,
- "userId": None,
- "codeModelMode": True,
- "agentMode": {},
- "trendingAgentMode": {},
- "isMicMode": False,
- "maxTokens": None,
- "isChromeExt": False,
- "githubToken": None,
- "clickedAnswer2": False,
- "clickedAnswer3": False,
- "clickedForceWebSearch": False,
- "visitFromDelta": False,
- "mobileClient": False
- }
+ ],
+ "id": chat_id,
+ "previewToken": None,
+ "userId": None,
+ "codeModelMode": True,
+ "agentMode": agent_mode,
+ "trendingAgentMode": trending_agent_mode,
+ "isMicMode": False,
+ "userSystemPrompt": None,
+ "maxTokens": 1024,
+ "playgroundTopP": 0.9,
+ "playgroundTemperature": 0.5,
+ "isChromeExt": False,
+ "githubToken": None,
+ "clickedAnswer2": False,
+ "clickedAnswer3": False,
+ "clickedForceWebSearch": False,
+ "visitFromDelta": False,
+ "mobileClient": False,
+ "webSearchMode": web_search,
+ "userSelectedModel": cls.userSelectedModel.get(model, model)
+ }
+
+ headers_chat = {
+ 'Accept': 'text/x-component',
+ 'Content-Type': 'text/plain;charset=UTF-8',
+ 'Referer': f'{cls.url}/chat/{chat_id}?model={model}',
+ 'next-action': next_action,
+ 'next-router-state-tree': next_router_state_tree,
+ 'next-url': '/'
+ }
+ headers_chat_combined = {**common_headers, **headers_chat}
+
+ data_chat = '[]'
+
+ async with ClientSession(headers=common_headers) as session:
+ try:
+ async with session.post(
+ cls.api_endpoint,
+ headers=headers_api_chat_combined,
+ json=payload_api_chat,
+ proxy=proxy
+ ) as response_api_chat:
+ response_api_chat.raise_for_status()
+ text = await response_api_chat.text()
+ cleaned_response = cls.clean_response(text)
- if model == 'ImageGenerationLV45LJp':
- data["agentMode"] = cls.model_config[model]
- else:
- data["trendingAgentMode"] = cls.model_config[model]
-
- async with session.post(cls.api_endpoint, json=data, proxy=proxy) as response:
- response.raise_for_status()
- if model == 'ImageGenerationLV45LJp':
- response_text = await response.text()
- url_match = re.search(r'https://storage\.googleapis\.com/[^\s\)]+', response_text)
- if url_match:
- image_url = url_match.group(0)
- yield ImageResponse(image_url, alt=messages[-1]['content'])
+ if model in cls.image_models:
+ match = re.search(r'!\[.*?\]\((https?://[^\)]+)\)', cleaned_response)
+ if match:
+ image_url = match.group(1)
+ image_response = ImageResponse(images=image_url, alt="Generated Image")
+ yield image_response
+ else:
+ yield cleaned_response
else:
- raise Exception("Image URL not found in the response")
- else:
- async for chunk in response.content:
- if chunk:
- decoded_chunk = chunk.decode()
- if decoded_chunk.startswith('$@$v=undefined-rv1$@$'):
- decoded_chunk = decoded_chunk[len('$@$v=undefined-rv1$@$'):]
- yield decoded_chunk
+ if web_search:
+ match = re.search(r'\$~~~\$(.*?)\$~~~\$', cleaned_response, re.DOTALL)
+ if match:
+ source_part = match.group(1).strip()
+ answer_part = cleaned_response[match.end():].strip()
+ try:
+ sources = json.loads(source_part)
+ source_formatted = "**Source:**\n"
+ for item in sources:
+ title = item.get('title', 'No Title')
+ link = item.get('link', '#')
+ position = item.get('position', '')
+ source_formatted += f"{position}. [{title}]({link})\n"
+ final_response = f"{answer_part}\n\n{source_formatted}"
+ except json.JSONDecodeError:
+ final_response = f"{answer_part}\n\nSource information is unavailable."
+ else:
+ final_response = cleaned_response
+ else:
+ if '$~~~$' in cleaned_response:
+ final_response = cleaned_response.split('$~~~$')[0].strip()
+ else:
+ final_response = cleaned_response
+
+ yield final_response
+ except ClientResponseError as e:
+ error_text = f"Error {e.status}: {e.message}"
+ try:
+ error_response = await e.response.text()
+ cleaned_error = cls.clean_response(error_response)
+ error_text += f" - {cleaned_error}"
+ except Exception:
+ pass
+ yield error_text
+ except Exception as e:
+ yield f"Unexpected error during /api/chat request: {str(e)}"
+
+ chat_url = f'{cls.url}/chat/{chat_id}?model={model}'
+
+ try:
+ async with session.post(
+ chat_url,
+ headers=headers_chat_combined,
+ data=data_chat,
+ proxy=proxy
+ ) as response_chat:
+ response_chat.raise_for_status()
+ pass
+ except ClientResponseError as e:
+ error_text = f"Error {e.status}: {e.message}"
+ try:
+ error_response = await e.response.text()
+ cleaned_error = cls.clean_response(error_response)
+ error_text += f" - {cleaned_error}"
+ except Exception:
+ pass
+ yield error_text
+ except Exception as e:
+ yield f"Unexpected error during /chat/{chat_id} request: {str(e)}"
diff --git a/g4f/Provider/ChatGpt.py b/g4f/Provider/ChatGpt.py
new file mode 100644
index 00000000..b5a78b9a
--- /dev/null
+++ b/g4f/Provider/ChatGpt.py
@@ -0,0 +1,225 @@
+from __future__ import annotations
+
+from ..typing import Messages, CreateResult
+from ..providers.base_provider import AbstractProvider, ProviderModelMixin
+
+import time, uuid, random, json
+from requests import Session
+
+from .openai.new import (
+ get_config,
+ get_answer_token,
+ process_turnstile,
+ get_requirements_token
+)
+
+def format_conversation(messages: list):
+ conversation = []
+
+ for message in messages:
+ conversation.append({
+ 'id': str(uuid.uuid4()),
+ 'author': {
+ 'role': message['role'],
+ },
+ 'content': {
+ 'content_type': 'text',
+ 'parts': [
+ message['content'],
+ ],
+ },
+ 'metadata': {
+ 'serialization_metadata': {
+ 'custom_symbol_offsets': [],
+ },
+ },
+ 'create_time': round(time.time(), 3),
+ })
+
+ return conversation
+
+def init_session(user_agent):
+ session = Session()
+
+ cookies = {
+ '_dd_s': '',
+ }
+
+ headers = {
+ 'accept': '*/*',
+ 'accept-language': 'en-US,en;q=0.8',
+ 'cache-control': 'no-cache',
+ 'pragma': 'no-cache',
+ 'priority': 'u=0, i',
+ 'sec-ch-ua': '"Not)A;Brand";v="99", "Google Chrome";v="127", "Chromium";v="127"',
+ 'sec-ch-ua-arch': '"arm"',
+ 'sec-ch-ua-bitness': '"64"',
+ 'sec-ch-ua-mobile': '?0',
+ 'sec-ch-ua-model': '""',
+ 'sec-ch-ua-platform': '"macOS"',
+ 'sec-ch-ua-platform-version': '"14.4.0"',
+ 'sec-fetch-dest': 'document',
+ 'sec-fetch-mode': 'navigate',
+ 'sec-fetch-site': 'none',
+ 'sec-fetch-user': '?1',
+ 'upgrade-insecure-requests': '1',
+ 'user-agent': user_agent,
+ }
+
+ session.get('https://chatgpt.com/', cookies=cookies, headers=headers)
+
+ return session
+
+class ChatGpt(AbstractProvider, ProviderModelMixin):
+ label = "ChatGpt"
+ working = True
+ supports_message_history = True
+ supports_system_message = True
+ supports_stream = True
+ models = [
+ 'gpt-4o',
+ 'gpt-4o-mini',
+ 'gpt-4',
+ 'gpt-4-turbo',
+ 'chatgpt-4o-latest',
+ ]
+
+ @classmethod
+ def create_completion(
+ cls,
+ model: str,
+ messages: Messages,
+ stream: bool,
+ **kwargs
+ ) -> CreateResult:
+
+ if model in [
+ 'gpt-4o',
+ 'gpt-4o-mini',
+ 'gpt-4',
+ 'gpt-4-turbo',
+ 'chatgpt-4o-latest'
+ ]:
+ model = 'auto'
+
+ elif model in [
+ 'gpt-3.5-turbo'
+ ]:
+ model = 'text-davinci-002-render-sha'
+
+ else:
+ raise ValueError(f"Invalid model: {model}")
+
+ user_agent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36'
+ session: Session = init_session(user_agent)
+
+ config = get_config(user_agent)
+ pow_req = get_requirements_token(config)
+ headers = {
+ 'accept': '*/*',
+ 'accept-language': 'en-US,en;q=0.8',
+ 'content-type': 'application/json',
+ 'oai-device-id': f'{uuid.uuid4()}',
+ 'oai-language': 'en-US',
+ 'origin': 'https://chatgpt.com',
+ 'priority': 'u=1, i',
+ 'referer': 'https://chatgpt.com/',
+ 'sec-ch-ua-mobile': '?0',
+ 'sec-ch-ua-platform': '"Linux"',
+ 'sec-fetch-dest': 'empty',
+ 'sec-fetch-mode': 'cors',
+ 'sec-fetch-site': 'same-origin',
+ 'sec-gpc': '1',
+ 'user-agent': f'{user_agent}'
+ }
+
+ response = session.post('https://chatgpt.com/backend-anon/sentinel/chat-requirements',
+ headers=headers, json={'p': pow_req})
+
+ if response.status_code != 200:
+ print(f"Request failed with status: {response.status_code}")
+ print(f"Response content: {response.content}")
+ return
+
+ response_data = response.json()
+ if "detail" in response_data and "Unusual activity" in response_data["detail"]:
+ print(f"Blocked due to unusual activity: {response_data['detail']}")
+ return
+
+ turnstile = response_data.get('turnstile', {})
+ turnstile_required = turnstile.get('required')
+ pow_conf = response_data.get('proofofwork', {})
+
+ if turnstile_required:
+ turnstile_dx = turnstile.get('dx')
+ turnstile_token = process_turnstile(turnstile_dx, pow_req)
+
+ headers = headers | {
+ 'openai-sentinel-turnstile-token' : turnstile_token,
+ 'openai-sentinel-chat-requirements-token': response_data.get('token'),
+ 'openai-sentinel-proof-token' : get_answer_token(
+ pow_conf.get('seed'), pow_conf.get('difficulty'), config
+ )
+ }
+
+ json_data = {
+ 'action': 'next',
+ 'messages': format_conversation(messages),
+ 'parent_message_id': str(uuid.uuid4()),
+ 'model': 'auto',
+ 'timezone_offset_min': -120,
+ 'suggestions': [
+ 'Can you help me create a personalized morning routine that would help increase my productivity throughout the day? Start by asking me about my current habits and what activities energize me in the morning.',
+ 'Could you help me plan a relaxing day that focuses on activities for rejuvenation? To start, can you ask me what my favorite forms of relaxation are?',
+ 'I have a photoshoot tomorrow. Can you recommend me some colors and outfit options that will look good on camera?',
+ 'Make up a 5-sentence story about "Sharky", a tooth-brushing shark superhero. Make each sentence a bullet point.',
+ ],
+ 'history_and_training_disabled': False,
+ 'conversation_mode': {
+ 'kind': 'primary_assistant',
+ },
+ 'force_paragen': False,
+ 'force_paragen_model_slug': '',
+ 'force_nulligen': False,
+ 'force_rate_limit': False,
+ 'reset_rate_limits': False,
+ 'websocket_request_id': str(uuid.uuid4()),
+ 'system_hints': [],
+ 'force_use_sse': True,
+ 'conversation_origin': None,
+ 'client_contextual_info': {
+ 'is_dark_mode': True,
+ 'time_since_loaded': random.randint(22,33),
+ 'page_height': random.randint(600, 900),
+ 'page_width': random.randint(500, 800),
+ 'pixel_ratio': 2,
+ 'screen_height': random.randint(800, 1200),
+ 'screen_width': random.randint(1200, 2000),
+ },
+ }
+
+ time.sleep(2)
+
+ response = session.post('https://chatgpt.com/backend-anon/conversation',
+ headers=headers, json=json_data, stream=True)
+
+ replace = ''
+ for line in response.iter_lines():
+ if line:
+ decoded_line = line.decode()
+ print(f"Received line: {decoded_line}")
+ if decoded_line.startswith('data:'):
+ json_string = decoded_line[6:]
+ if json_string.strip():
+ try:
+ data = json.loads(json_string)
+ except json.JSONDecodeError as e:
+ print(f"Error decoding JSON: {e}, content: {json_string}")
+ continue
+
+ if data.get('message').get('author').get('role') == 'assistant':
+ tokens = (data.get('message').get('content').get('parts')[0])
+
+ yield tokens.replace(replace, '')
+
+ replace = tokens
diff --git a/g4f/Provider/ChatGptEs.py b/g4f/Provider/ChatGptEs.py
new file mode 100644
index 00000000..a060ecb1
--- /dev/null
+++ b/g4f/Provider/ChatGptEs.py
@@ -0,0 +1,84 @@
+from __future__ import annotations
+
+from aiohttp import ClientSession
+import os
+import json
+import re
+
+from ..typing import AsyncResult, Messages
+from .base_provider import AsyncGeneratorProvider, ProviderModelMixin
+from .helper import format_prompt
+
+class ChatGptEs(AsyncGeneratorProvider, ProviderModelMixin):
+ url = "https://chatgpt.es"
+ api_endpoint = "https://chatgpt.es/wp-admin/admin-ajax.php"
+ working = True
+ supports_stream = True
+ supports_system_message = True
+ supports_message_history = True
+
+ default_model = 'gpt-4o'
+ models = ['gpt-4o', 'gpt-4o-mini', 'chatgpt-4o-latest']
+
+ model_aliases = {
+ "gpt-4o": "chatgpt-4o-latest",
+ }
+
+ @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,
+ proxy: str = None,
+ **kwargs
+ ) -> AsyncResult:
+ model = cls.get_model(model)
+
+ headers = {
+ "authority": "chatgpt.es",
+ "accept": "application/json",
+ "origin": cls.url,
+ "referer": f"{cls.url}/chat",
+ "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36",
+ }
+
+ async with ClientSession(headers=headers) as session:
+ initial_response = await session.get(cls.url)
+ nonce_ = re.findall(r'data-nonce="(.+?)"', await initial_response.text())[0]
+ post_id = re.findall(r'data-post-id="(.+?)"', await initial_response.text())[0]
+
+ conversation_history = [
+ "Human: strictly respond in the same language as my prompt, preferably English"
+ ]
+
+ for message in messages[:-1]:
+ if message['role'] == "user":
+ conversation_history.append(f"Human: {message['content']}")
+ else:
+ conversation_history.append(f"AI: {message['content']}")
+
+ payload = {
+ '_wpnonce': nonce_,
+ 'post_id': post_id,
+ 'url': cls.url,
+ 'action': 'wpaicg_chat_shortcode_message',
+ 'message': messages[-1]['content'],
+ 'bot_id': '0',
+ 'chatbot_identity': 'shortcode',
+ 'wpaicg_chat_client_id': os.urandom(5).hex(),
+ 'wpaicg_chat_history': json.dumps(conversation_history)
+ }
+
+ async with session.post(cls.api_endpoint, headers=headers, data=payload) as response:
+ response.raise_for_status()
+ result = await response.json()
+ yield result['data']
diff --git a/g4f/Provider/ChatHub.py b/g4f/Provider/ChatHub.py
new file mode 100644
index 00000000..3b762687
--- /dev/null
+++ b/g4f/Provider/ChatHub.py
@@ -0,0 +1,84 @@
+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 ChatHub(AsyncGeneratorProvider, ProviderModelMixin):
+ label = "ChatHub"
+ url = "https://app.chathub.gg"
+ api_endpoint = "https://app.chathub.gg/api/v3/chat/completions"
+ working = True
+ supports_stream = True
+ supports_system_message = True
+ supports_message_history = True
+
+ default_model = 'meta/llama3.1-8b'
+ models = [
+ 'meta/llama3.1-8b',
+ 'mistral/mixtral-8x7b',
+ 'google/gemma-2',
+ 'perplexity/sonar-online',
+ ]
+
+ model_aliases = {
+ "llama-3.1-8b": "meta/llama3.1-8b",
+ "mixtral-8x7b": "mistral/mixtral-8x7b",
+ "gemma-2": "google/gemma-2",
+ "sonar-online": "perplexity/sonar-online",
+ }
+
+ @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,
+ proxy: str = None,
+ **kwargs
+ ) -> AsyncResult:
+ model = cls.get_model(model)
+
+ headers = {
+ 'accept': '*/*',
+ 'accept-language': 'en-US,en;q=0.9',
+ 'content-type': 'application/json',
+ 'origin': cls.url,
+ 'referer': f"{cls.url}/chat/cloud-llama3.1-8b",
+ 'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36',
+ 'x-app-id': 'web'
+ }
+
+ async with ClientSession(headers=headers) as session:
+ prompt = format_prompt(messages)
+ data = {
+ "model": model,
+ "messages": [{"role": "user", "content": prompt}],
+ "tools": []
+ }
+
+ 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:
+ decoded_line = line.decode('utf-8')
+ if decoded_line.startswith('data:'):
+ try:
+ data = json.loads(decoded_line[5:])
+ if data['type'] == 'text-delta':
+ yield data['textDelta']
+ elif data['type'] == 'done':
+ break
+ except json.JSONDecodeError:
+ continue
diff --git a/g4f/Provider/Chatgpt4Online.py b/g4f/Provider/Chatgpt4Online.py
index 8c058fdc..627facf6 100644
--- a/g4f/Provider/Chatgpt4Online.py
+++ b/g4f/Provider/Chatgpt4Online.py
@@ -12,13 +12,15 @@ class Chatgpt4Online(AsyncGeneratorProvider):
url = "https://chatgpt4online.org"
api_endpoint = "/wp-json/mwai-ui/v1/chats/submit"
working = True
- supports_gpt_4 = True
+
+ default_model = 'gpt-4'
+ models = [default_model]
async def get_nonce(headers: dict) -> str:
async with ClientSession(headers=headers) as session:
async with session.post(f"https://chatgpt4online.org/wp-json/mwai/v1/start_session") as response:
return (await response.json())["restNonce"]
-
+
@classmethod
async def create_async_generator(
cls,
diff --git a/g4f/Provider/Chatgpt4o.py b/g4f/Provider/Chatgpt4o.py
index f3dc8a15..7730fc84 100644
--- a/g4f/Provider/Chatgpt4o.py
+++ b/g4f/Provider/Chatgpt4o.py
@@ -9,11 +9,16 @@ from .helper import format_prompt
class Chatgpt4o(AsyncProvider, ProviderModelMixin):
url = "https://chatgpt4o.one"
- supports_gpt_4 = True
working = True
_post_id = None
_nonce = None
- default_model = 'gpt-4o'
+ default_model = 'gpt-4o-mini-2024-07-18'
+ models = [
+ 'gpt-4o-mini-2024-07-18',
+ ]
+ model_aliases = {
+ "gpt-4o-mini": "gpt-4o-mini-2024-07-18",
+ }
@classmethod
diff --git a/g4f/Provider/ChatgptFree.py b/g4f/Provider/ChatgptFree.py
index 95efa865..d2837594 100644
--- a/g4f/Provider/ChatgptFree.py
+++ b/g4f/Provider/ChatgptFree.py
@@ -10,7 +10,6 @@ from .helper import format_prompt
class ChatgptFree(AsyncGeneratorProvider, ProviderModelMixin):
url = "https://chatgptfree.ai"
- supports_gpt_4 = True
working = True
_post_id = None
_nonce = None
diff --git a/g4f/Provider/ChatifyAI.py b/g4f/Provider/ChatifyAI.py
new file mode 100644
index 00000000..7e43b065
--- /dev/null
+++ b/g4f/Provider/ChatifyAI.py
@@ -0,0 +1,79 @@
+from __future__ import annotations
+
+from aiohttp import ClientSession
+
+from ..typing import AsyncResult, Messages
+from .base_provider import AsyncGeneratorProvider, ProviderModelMixin
+from .helper import format_prompt
+
+
+class ChatifyAI(AsyncGeneratorProvider, ProviderModelMixin):
+ url = "https://chatify-ai.vercel.app"
+ api_endpoint = "https://chatify-ai.vercel.app/api/chat"
+ working = True
+ supports_stream = False
+ supports_system_message = True
+ supports_message_history = True
+
+ default_model = 'llama-3.1'
+ models = [default_model]
+ model_aliases = {
+ "llama-3.1-8b": "llama-3.1",
+ }
+
+ @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.get(model, cls.default_model)
+ else:
+ return cls.default_model
+
+ @classmethod
+ async def create_async_generator(
+ cls,
+ model: str,
+ messages: Messages,
+ proxy: str = None,
+ **kwargs
+ ) -> AsyncResult:
+ model = cls.get_model(model)
+
+ headers = {
+ "accept": "*/*",
+ "accept-language": "en-US,en;q=0.9",
+ "cache-control": "no-cache",
+ "content-type": "application/json",
+ "origin": cls.url,
+ "pragma": "no-cache",
+ "priority": "u=1, i",
+ "referer": f"{cls.url}/",
+ "sec-ch-ua": '"Chromium";v="129", "Not=A?Brand";v="8"',
+ "sec-ch-ua-mobile": "?0",
+ "sec-ch-ua-platform": '"Linux"',
+ "sec-fetch-dest": "empty",
+ "sec-fetch-mode": "cors",
+ "sec-fetch-site": "same-origin",
+ "user-agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36"
+ }
+ async with ClientSession(headers=headers) as session:
+ data = {
+ "messages": [{"role": "user", "content": format_prompt(messages)}]
+ }
+ async with session.post(cls.api_endpoint, json=data, proxy=proxy) as response:
+ response.raise_for_status()
+ response_text = await response.text()
+
+ filtered_response = cls.filter_response(response_text)
+ yield filtered_response
+
+ @staticmethod
+ def filter_response(response_text: str) -> str:
+ parts = response_text.split('"')
+
+ text_parts = parts[1::2]
+
+ clean_text = ''.join(text_parts)
+
+ return clean_text
diff --git a/g4f/Provider/Cloudflare.py b/g4f/Provider/Cloudflare.py
new file mode 100644
index 00000000..e78bbcd0
--- /dev/null
+++ b/g4f/Provider/Cloudflare.py
@@ -0,0 +1,212 @@
+from __future__ import annotations
+
+import asyncio
+import json
+import uuid
+import cloudscraper
+from typing import AsyncGenerator
+from ..typing import AsyncResult, Messages
+from .base_provider import AsyncGeneratorProvider, ProviderModelMixin
+from .helper import format_prompt
+
+class Cloudflare(AsyncGeneratorProvider, ProviderModelMixin):
+ url = "https://playground.ai.cloudflare.com"
+ api_endpoint = "https://playground.ai.cloudflare.com/api/inference"
+ working = True
+ supports_stream = True
+ supports_system_message = True
+ supports_message_history = True
+
+ default_model = '@cf/meta/llama-3.1-8b-instruct'
+ models = [
+ '@cf/deepseek-ai/deepseek-math-7b-instruct', # Specific answer
+
+
+ '@cf/thebloke/discolm-german-7b-v1-awq',
+
+
+ '@cf/tiiuae/falcon-7b-instruct', # Specific answer
+
+
+ '@hf/google/gemma-7b-it',
+
+
+ '@cf/meta/llama-2-7b-chat-fp16',
+ '@cf/meta/llama-2-7b-chat-int8',
+
+ '@cf/meta/llama-3-8b-instruct',
+ '@cf/meta/llama-3-8b-instruct-awq',
+ default_model,
+ '@hf/meta-llama/meta-llama-3-8b-instruct',
+
+ '@cf/meta/llama-3.1-8b-instruct-awq',
+ '@cf/meta/llama-3.1-8b-instruct-fp8',
+ '@cf/meta/llama-3.2-11b-vision-instruct',
+ '@cf/meta/llama-3.2-1b-instruct',
+ '@cf/meta/llama-3.2-3b-instruct',
+
+ '@cf/mistral/mistral-7b-instruct-v0.1',
+ '@hf/mistral/mistral-7b-instruct-v0.2',
+
+ '@cf/openchat/openchat-3.5-0106',
+
+ '@cf/microsoft/phi-2',
+
+ '@cf/qwen/qwen1.5-0.5b-chat',
+ '@cf/qwen/qwen1.5-1.8b-chat',
+ '@cf/qwen/qwen1.5-14b-chat-awq',
+ '@cf/qwen/qwen1.5-7b-chat-awq',
+
+ '@cf/defog/sqlcoder-7b-2', # Specific answer
+
+ '@cf/tinyllama/tinyllama-1.1b-chat-v1.0',
+
+ '@cf/fblgit/una-cybertron-7b-v2-bf16',
+ ]
+
+ model_aliases = {
+ "german-7b-v1": "@cf/thebloke/discolm-german-7b-v1-awq",
+
+
+ "gemma-7b": "@hf/google/gemma-7b-it",
+
+
+ "llama-2-7b": "@cf/meta/llama-2-7b-chat-fp16",
+ "llama-2-7b": "@cf/meta/llama-2-7b-chat-int8",
+
+ "llama-3-8b": "@cf/meta/llama-3-8b-instruct",
+ "llama-3-8b": "@cf/meta/llama-3-8b-instruct-awq",
+ "llama-3-8b": "@cf/meta/llama-3.1-8b-instruct",
+ "llama-3-8b": "@hf/meta-llama/meta-llama-3-8b-instruct",
+
+ "llama-3.1-8b": "@cf/meta/llama-3.1-8b-instruct-awq",
+ "llama-3.1-8b": "@cf/meta/llama-3.1-8b-instruct-fp8",
+ "llama-3.1-8b": "@cf/meta/llama-3.1-8b-instruct-fp8",
+
+ "llama-3.2-11b": "@cf/meta/llama-3.2-11b-vision-instruct",
+ "llama-3.2-1b": "@cf/meta/llama-3.2-1b-instruct",
+ "llama-3.2-3b": "@cf/meta/llama-3.2-3b-instruct",
+
+
+ "mistral-7b": "@cf/mistral/mistral-7b-instruct-v0.1",
+ "mistral-7b": "@hf/mistral/mistral-7b-instruct-v0.2",
+
+
+ "openchat-3.5": "@cf/openchat/openchat-3.5-0106",
+
+
+ "phi-2": "@cf/microsoft/phi-2",
+
+
+ "qwen-1.5-0.5b": "@cf/qwen/qwen1.5-0.5b-chat",
+ "qwen-1.5-1.8b": "@cf/qwen/qwen1.5-1.8b-chat",
+ "qwen-1.5-14b": "@cf/qwen/qwen1.5-14b-chat-awq",
+ "qwen-1.5-7b": "@cf/qwen/qwen1.5-7b-chat-awq",
+
+
+ "tinyllama-1.1b": "@cf/tinyllama/tinyllama-1.1b-chat-v1.0",
+
+
+ "cybertron-7b": "@cf/fblgit/una-cybertron-7b-v2-bf16",
+ }
+
+ @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,
+ proxy: str = None,
+ max_tokens: str = 2048,
+ stream: bool = True,
+ **kwargs
+ ) -> AsyncResult:
+ model = cls.get_model(model)
+
+ headers = {
+ 'Accept': 'text/event-stream',
+ 'Accept-Language': 'en-US,en;q=0.9',
+ 'Cache-Control': 'no-cache',
+ 'Content-Type': 'application/json',
+ 'Origin': cls.url,
+ 'Pragma': 'no-cache',
+ 'Referer': f'{cls.url}/',
+ 'Sec-Ch-Ua': '"Chromium";v="129", "Not=A?Brand";v="8"',
+ 'Sec-Ch-Ua-Mobile': '?0',
+ 'Sec-Ch-Ua-Platform': '"Linux"',
+ 'Sec-Fetch-Dest': 'empty',
+ 'Sec-Fetch-Mode': 'cors',
+ 'Sec-Fetch-Site': 'same-origin',
+ 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36',
+ }
+
+ cookies = {
+ '__cf_bm': uuid.uuid4().hex,
+ }
+
+ scraper = cloudscraper.create_scraper()
+
+ prompt = format_prompt(messages)
+ data = {
+ "messages": [
+ {"role": "system", "content": "You are a helpful assistant"},
+ {"role": "user", "content": prompt}
+ ],
+ "lora": None,
+ "model": model,
+ "max_tokens": max_tokens,
+ "stream": stream
+ }
+
+ max_retries = 3
+ for attempt in range(max_retries):
+ try:
+ response = scraper.post(
+ cls.api_endpoint,
+ headers=headers,
+ cookies=cookies,
+ json=data,
+ stream=True,
+ proxies={'http': proxy, 'https': proxy} if proxy else None
+ )
+
+ if response.status_code == 403:
+ await asyncio.sleep(2 ** attempt)
+ continue
+
+ response.raise_for_status()
+
+ for line in response.iter_lines():
+ if line.startswith(b'data: '):
+ if line == b'data: [DONE]':
+ break
+ try:
+ content = json.loads(line[6:].decode('utf-8'))['response']
+ yield content
+ except Exception:
+ continue
+ break
+ except Exception as e:
+ if attempt == max_retries - 1:
+ raise
+
+ @classmethod
+ async def create_async(
+ cls,
+ model: str,
+ messages: Messages,
+ proxy: str = None,
+ **kwargs
+ ) -> str:
+ full_response = ""
+ async for response in cls.create_async_generator(model, messages, proxy, **kwargs):
+ full_response += response
+ return full_response
diff --git a/g4f/Provider/CodeNews.py b/g4f/Provider/CodeNews.py
deleted file mode 100644
index 05ec7a45..00000000
--- a/g4f/Provider/CodeNews.py
+++ /dev/null
@@ -1,94 +0,0 @@
-from __future__ import annotations
-
-from aiohttp import ClientSession
-from asyncio import sleep
-
-from ..typing import AsyncResult, Messages
-from .base_provider import AsyncGeneratorProvider, ProviderModelMixin
-from .helper import format_prompt
-
-
-class CodeNews(AsyncGeneratorProvider, ProviderModelMixin):
- url = "https://codenews.cc"
- api_endpoint = "https://codenews.cc/chatxyz13"
- working = True
- supports_gpt_35_turbo = True
- supports_gpt_4 = False
- supports_stream = True
- supports_system_message = False
- supports_message_history = False
-
- default_model = 'free_gpt'
- models = ['free_gpt', 'gpt-4o-mini', 'deepseek-coder', 'chatpdf']
-
- model_aliases = {
- "glm-4": "free_gpt",
- "gpt-3.5-turbo": "chatpdf",
- "deepseek": "deepseek-coder",
- }
-
- @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,
- proxy: str = None,
- **kwargs
- ) -> AsyncResult:
- model = cls.get_model(model)
-
- headers = {
- "accept": "application/json, text/javascript, */*; q=0.01",
- "accept-language": "en-US,en;q=0.9",
- "cache-control": "no-cache",
- "content-type": "application/x-www-form-urlencoded; charset=UTF-8",
- "origin": cls.url,
- "pragma": "no-cache",
- "priority": "u=1, i",
- "referer": f"{cls.url}/chatgpt",
- "sec-ch-ua": '"Chromium";v="127", "Not)A;Brand";v="99"',
- "sec-ch-ua-mobile": "?0",
- "sec-ch-ua-platform": '"Linux"',
- "sec-fetch-dest": "empty",
- "sec-fetch-mode": "cors",
- "sec-fetch-site": "same-origin",
- "user-agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36",
- "x-requested-with": "XMLHttpRequest",
- }
- async with ClientSession(headers=headers) as session:
- prompt = format_prompt(messages)
- data = {
- "chatgpt_input": prompt,
- "qa_type2": model,
- "chatgpt_version_value": "20240804",
- "enable_web_search": "0",
- "enable_agent": "0",
- "dy_video_text_extract": "0",
- "enable_summary": "0",
- }
- async with session.post(cls.api_endpoint, data=data, proxy=proxy) as response:
- response.raise_for_status()
- json_data = await response.json()
- chat_id = json_data["data"]["id"]
-
- headers["content-type"] = "application/x-www-form-urlencoded; charset=UTF-8"
- data = {"current_req_count": "2"}
-
- while True:
- async with session.post(f"{cls.url}/chat_stream", headers=headers, data=data, proxy=proxy) as response:
- response.raise_for_status()
- json_data = await response.json()
- if json_data["data"]:
- yield json_data["data"]
- break
- else:
- await sleep(1) # Затримка перед наступним запитом
diff --git a/g4f/Provider/DDG.py b/g4f/Provider/DDG.py
index c8c36fc9..43cc39c0 100644
--- a/g4f/Provider/DDG.py
+++ b/g4f/Provider/DDG.py
@@ -2,115 +2,107 @@ from __future__ import annotations
import json
import aiohttp
-import asyncio
-from typing import Optional
-import base64
+from aiohttp import ClientSession
-from .base_provider import AsyncGeneratorProvider, ProviderModelMixin
-from .helper import get_connector
from ..typing import AsyncResult, Messages
-from ..requests.raise_for_status import raise_for_status
-from ..providers.conversation import BaseConversation
+from .base_provider import AsyncGeneratorProvider, ProviderModelMixin
+from .helper import format_prompt
+
class DDG(AsyncGeneratorProvider, ProviderModelMixin):
- url = base64.b64decode("aHR0cHM6Ly9kdWNrZHVja2dvLmNvbS9haWNoYXQ=").decode("utf-8")
+ url = "https://duckduckgo.com"
+ api_endpoint = "https://duckduckgo.com/duckchat/v1/chat"
working = True
- supports_gpt_35_turbo = True
+ supports_stream = True
+ supports_system_message = True
supports_message_history = True
default_model = "gpt-4o-mini"
- models = ["gpt-4o-mini", "claude-3-haiku-20240307", "meta-llama/Meta-Llama-3.1-70B-Instruct-Turbo", "mistralai/Mixtral-8x7B-Instruct-v0.1"]
+ models = [
+ "gpt-4o-mini",
+ "claude-3-haiku-20240307",
+ "meta-llama/Meta-Llama-3.1-70B-Instruct-Turbo",
+ "mistralai/Mixtral-8x7B-Instruct-v0.1"
+ ]
model_aliases = {
"claude-3-haiku": "claude-3-haiku-20240307",
"llama-3.1-70b": "meta-llama/Meta-Llama-3.1-70B-Instruct-Turbo",
"mixtral-8x7b": "mistralai/Mixtral-8x7B-Instruct-v0.1"
}
- # Obfuscated URLs and headers
- status_url = base64.b64decode("aHR0cHM6Ly9kdWNrZHVja2dvLmNvbS9kdWNrY2hhdC92MS9zdGF0dXM=").decode("utf-8")
- chat_url = base64.b64decode("aHR0cHM6Ly9kdWNrZHVja2dvLmNvbS9kdWNrY2hhdC92MS9jaGF0").decode("utf-8")
- referer = base64.b64decode("aHR0cHM6Ly9kdWNrZHVja2dvLmNvbS8=").decode("utf-8")
- origin = base64.b64decode("aHR0cHM6Ly9kdWNrZHVja2dvLmNvbQ==").decode("utf-8")
-
- user_agent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36'
- headers = {
- 'User-Agent': user_agent,
- 'Accept': 'text/event-stream',
- 'Accept-Language': 'en-US,en;q=0.5',
- 'Accept-Encoding': 'gzip, deflate, br, zstd',
- 'Referer': referer,
- 'Content-Type': 'application/json',
- 'Origin': origin,
- 'Connection': 'keep-alive',
- 'Cookie': 'dcm=3',
- 'Sec-Fetch-Dest': 'empty',
- 'Sec-Fetch-Mode': 'cors',
- 'Sec-Fetch-Site': 'same-origin',
- 'Pragma': 'no-cache',
- 'TE': 'trailers'
- }
+ @classmethod
+ def get_model(cls, model: str) -> str:
+ return cls.model_aliases.get(model, model) if model in cls.model_aliases else cls.default_model
@classmethod
- async def get_vqd(cls, session: aiohttp.ClientSession) -> Optional[str]:
- try:
- async with session.get(cls.status_url, headers={"x-vqd-accept": "1"}) as response:
- await raise_for_status(response)
- return response.headers.get("x-vqd-4")
- except Exception as e:
- print(f"Error getting VQD: {e}")
- return None
+ async def get_vqd(cls):
+ status_url = "https://duckduckgo.com/duckchat/v1/status"
+
+ headers = {
+ 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36',
+ 'Accept': 'text/event-stream',
+ 'x-vqd-accept': '1'
+ }
+
+ async with aiohttp.ClientSession() as session:
+ try:
+ async with session.get(status_url, headers=headers) as response:
+ if response.status == 200:
+ return response.headers.get("x-vqd-4")
+ else:
+ print(f"Error: Status code {response.status}")
+ return None
+ except Exception as e:
+ print(f"Error getting VQD: {e}")
+ return None
@classmethod
async def create_async_generator(
cls,
model: str,
messages: Messages,
+ conversation: dict = None,
proxy: str = None,
- connector: aiohttp.BaseConnector = None,
- conversation: Conversation = None,
- return_conversation: bool = False,
**kwargs
) -> AsyncResult:
- async with aiohttp.ClientSession(headers=cls.headers, connector=get_connector(connector, proxy)) as session:
- vqd_4 = None
- if conversation is not None and len(messages) > 1:
- vqd_4 = conversation.vqd_4
- messages = [*conversation.messages, messages[-2], messages[-1]]
- else:
- for _ in range(3): # Try up to 3 times to get a valid VQD
- vqd_4 = await cls.get_vqd(session)
- if vqd_4:
- break
- await asyncio.sleep(1) # Wait a bit before retrying
-
- if not vqd_4:
- raise Exception("Failed to obtain a valid VQD token")
-
- messages = [messages[-1]] # Only use the last message for new conversations
-
- payload = {
- 'model': cls.get_model(model),
- 'messages': [{'role': m['role'], 'content': m['content']} for m in messages]
+ model = cls.get_model(model)
+
+ headers = {
+ 'accept': 'text/event-stream',
+ 'content-type': 'application/json',
+ 'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36',
+ }
+
+ vqd = conversation.get('vqd') if conversation else await cls.get_vqd()
+ if not vqd:
+ raise Exception("Failed to obtain VQD token")
+
+ headers['x-vqd-4'] = vqd
+
+ if conversation:
+ message_history = conversation.get('messages', [])
+ message_history.append({"role": "user", "content": format_prompt(messages)})
+ else:
+ message_history = [{"role": "user", "content": format_prompt(messages)}]
+
+ async with ClientSession(headers=headers) as session:
+ data = {
+ "model": model,
+ "messages": message_history
}
-
- async with session.post(cls.chat_url, json=payload, headers={"x-vqd-4": vqd_4}) as response:
- await raise_for_status(response)
- if return_conversation:
- yield Conversation(vqd_4, messages)
-
- async for line in response.content:
- if line.startswith(b"data: "):
- chunk = line[6:]
- if chunk.startswith(b"[DONE]"):
- break
- try:
- data = json.loads(chunk)
- if "message" in data and data["message"]:
- yield data["message"]
- except json.JSONDecodeError:
- print(f"Failed to decode JSON: {chunk}")
-class Conversation(BaseConversation):
- def __init__(self, vqd_4: str, messages: Messages) -> None:
- self.vqd_4 = vqd_4
- self.messages = messages
+ 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:
+ decoded_line = line.decode('utf-8')
+ if decoded_line.startswith('data: '):
+ json_str = decoded_line[6:]
+ if json_str == '[DONE]':
+ break
+ try:
+ json_data = json.loads(json_str)
+ if 'message' in json_data:
+ yield json_data['message']
+ except json.JSONDecodeError:
+ pass
diff --git a/g4f/Provider/DarkAI.py b/g4f/Provider/DarkAI.py
new file mode 100644
index 00000000..6ffb615e
--- /dev/null
+++ b/g4f/Provider/DarkAI.py
@@ -0,0 +1,85 @@
+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 DarkAI(AsyncGeneratorProvider, ProviderModelMixin):
+ url = "https://www.aiuncensored.info"
+ api_endpoint = "https://darkai.foundation/chat"
+ working = True
+ supports_stream = True
+ supports_system_message = True
+ supports_message_history = True
+
+ default_model = 'gpt-4o'
+ models = [
+ default_model, # Uncensored
+ 'gpt-3.5-turbo', # Uncensored
+ 'llama-3-70b', # Uncensored
+ 'llama-3-405b',
+ ]
+
+ model_aliases = {
+ "llama-3.1-70b": "llama-3-70b",
+ "llama-3.1-405b": "llama-3-405b",
+ }
+
+ @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,
+ proxy: str = None,
+ **kwargs
+ ) -> AsyncResult:
+ model = cls.get_model(model)
+
+ headers = {
+ "accept": "text/event-stream",
+ "content-type": "application/json",
+ "origin": "https://www.aiuncensored.info",
+ "referer": "https://www.aiuncensored.info/",
+ "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36"
+ }
+ async with ClientSession(headers=headers) as session:
+ prompt = format_prompt(messages)
+ data = {
+ "query": prompt,
+ "model": model,
+ }
+ async with session.post(cls.api_endpoint, json=data, proxy=proxy) as response:
+ response.raise_for_status()
+ full_text = ""
+ async for chunk in response.content:
+ if chunk:
+ try:
+ chunk_str = chunk.decode().strip()
+ if chunk_str.startswith('data: '):
+ chunk_data = json.loads(chunk_str[6:])
+ if chunk_data['event'] == 'text-chunk':
+ full_text += chunk_data['data']['text']
+ elif chunk_data['event'] == 'stream-end':
+ if full_text:
+ yield full_text.strip()
+ return
+ except json.JSONDecodeError:
+ print(f"Failed to decode JSON: {chunk_str}")
+ except Exception as e:
+ print(f"Error processing chunk: {e}")
+
+ if full_text:
+ yield full_text.strip()
diff --git a/g4f/Provider/DeepInfraChat.py b/g4f/Provider/DeepInfraChat.py
new file mode 100644
index 00000000..b8cc6ab8
--- /dev/null
+++ b/g4f/Provider/DeepInfraChat.py
@@ -0,0 +1,142 @@
+from __future__ import annotations
+
+from aiohttp import ClientSession
+import json
+
+from ..typing import AsyncResult, Messages, ImageType
+from ..image import to_data_uri
+from .base_provider import AsyncGeneratorProvider, ProviderModelMixin
+from .helper import format_prompt
+
+
+class DeepInfraChat(AsyncGeneratorProvider, ProviderModelMixin):
+ url = "https://deepinfra.com/chat"
+ api_endpoint = "https://api.deepinfra.com/v1/openai/chat/completions"
+ working = True
+ supports_stream = True
+ supports_system_message = True
+ supports_message_history = True
+
+ default_model = 'meta-llama/Meta-Llama-3.1-70B-Instruct'
+ models = [
+ 'meta-llama/Meta-Llama-3.1-405B-Instruct',
+ 'meta-llama/Meta-Llama-3.1-70B-Instruct',
+ 'meta-llama/Meta-Llama-3.1-8B-Instruct',
+ 'mistralai/Mixtral-8x22B-Instruct-v0.1',
+ 'mistralai/Mixtral-8x7B-Instruct-v0.1',
+ 'microsoft/WizardLM-2-8x22B',
+ 'microsoft/WizardLM-2-7B',
+ 'Qwen/Qwen2-72B-Instruct',
+ 'microsoft/Phi-3-medium-4k-instruct',
+ 'google/gemma-2-27b-it',
+ 'openbmb/MiniCPM-Llama3-V-2_5', # Image upload is available
+ 'mistralai/Mistral-7B-Instruct-v0.3',
+ 'lizpreciatior/lzlv_70b_fp16_hf',
+ 'openchat/openchat-3.6-8b',
+ 'Phind/Phind-CodeLlama-34B-v2',
+ 'cognitivecomputations/dolphin-2.9.1-llama-3-70b',
+ ]
+ model_aliases = {
+ "llama-3.1-405b": "meta-llama/Meta-Llama-3.1-405B-Instruct",
+ "llama-3.1-70b": "meta-llama/Meta-Llama-3.1-70B-Instruct",
+ "llama-3.1-8B": "meta-llama/Meta-Llama-3.1-8B-Instruct",
+ "mixtral-8x22b": "mistralai/Mixtral-8x22B-Instruct-v0.1",
+ "mixtral-8x7b": "mistralai/Mixtral-8x7B-Instruct-v0.1",
+ "wizardlm-2-8x22b": "microsoft/WizardLM-2-8x22B",
+ "wizardlm-2-7b": "microsoft/WizardLM-2-7B",
+ "qwen-2-72b": "Qwen/Qwen2-72B-Instruct",
+ "phi-3-medium-4k": "microsoft/Phi-3-medium-4k-instruct",
+ "gemma-2b-27b": "google/gemma-2-27b-it",
+ "minicpm-llama-3-v2.5": "openbmb/MiniCPM-Llama3-V-2_5", # Image upload is available
+ "mistral-7b": "mistralai/Mistral-7B-Instruct-v0.3",
+ "lzlv-70b": "lizpreciatior/lzlv_70b_fp16_hf",
+ "openchat-3.6-8b": "openchat/openchat-3.6-8b",
+ "phind-codellama-34b-v2": "Phind/Phind-CodeLlama-34B-v2",
+ "dolphin-2.9.1-llama-3-70b": "cognitivecomputations/dolphin-2.9.1-llama-3-70b",
+ }
+
+
+ @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,
+ proxy: str = None,
+ image: ImageType = None,
+ image_name: str = None,
+ **kwargs
+ ) -> AsyncResult:
+ model = cls.get_model(model)
+
+ headers = {
+ 'Accept-Language': 'en-US,en;q=0.9',
+ 'Cache-Control': 'no-cache',
+ 'Connection': 'keep-alive',
+ 'Content-Type': 'application/json',
+ 'Origin': 'https://deepinfra.com',
+ 'Pragma': 'no-cache',
+ 'Referer': 'https://deepinfra.com/',
+ 'Sec-Fetch-Dest': 'empty',
+ 'Sec-Fetch-Mode': 'cors',
+ 'Sec-Fetch-Site': 'same-site',
+ 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36',
+ 'X-Deepinfra-Source': 'web-embed',
+ 'accept': 'text/event-stream',
+ 'sec-ch-ua': '"Not;A=Brand";v="24", "Chromium";v="128"',
+ 'sec-ch-ua-mobile': '?0',
+ 'sec-ch-ua-platform': '"Linux"',
+ }
+
+ async with ClientSession(headers=headers) as session:
+ prompt = format_prompt(messages)
+ data = {
+ 'model': model,
+ 'messages': [
+ {'role': 'system', 'content': 'Be a helpful assistant'},
+ {'role': 'user', 'content': prompt}
+ ],
+ 'stream': True
+ }
+
+ if model == 'openbmb/MiniCPM-Llama3-V-2_5' and image is not None:
+ data['messages'][-1]['content'] = [
+ {
+ 'type': 'image_url',
+ 'image_url': {
+ 'url': to_data_uri(image)
+ }
+ },
+ {
+ 'type': 'text',
+ 'text': messages[-1]['content']
+ }
+ ]
+
+ 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:
+ decoded_line = line.decode('utf-8').strip()
+ if decoded_line.startswith('data:'):
+ json_part = decoded_line[5:].strip()
+ if json_part == '[DONE]':
+ break
+ try:
+ data = json.loads(json_part)
+ choices = data.get('choices', [])
+ if choices:
+ delta = choices[0].get('delta', {})
+ content = delta.get('content', '')
+ if content:
+ yield content
+ except json.JSONDecodeError:
+ print(f"JSON decode error: {json_part}")
diff --git a/g4f/Provider/DeepInfraImage.py b/g4f/Provider/DeepInfraImage.py
index 46a5c2e2..cee608ce 100644
--- a/g4f/Provider/DeepInfraImage.py
+++ b/g4f/Provider/DeepInfraImage.py
@@ -11,7 +11,8 @@ class DeepInfraImage(AsyncGeneratorProvider, ProviderModelMixin):
url = "https://deepinfra.com"
parent = "DeepInfra"
working = True
- default_model = 'stability-ai/sdxl'
+ needs_auth = True
+ default_model = ''
image_models = [default_model]
@classmethod
@@ -76,4 +77,4 @@ class DeepInfraImage(AsyncGeneratorProvider, ProviderModelMixin):
if not images:
raise RuntimeError(f"Response: {data}")
images = images[0] if len(images) == 1 else images
- return ImageResponse(images, prompt) \ No newline at end of file
+ return ImageResponse(images, prompt)
diff --git a/g4f/Provider/Editee.py b/g4f/Provider/Editee.py
new file mode 100644
index 00000000..8ac2324a
--- /dev/null
+++ b/g4f/Provider/Editee.py
@@ -0,0 +1,77 @@
+from __future__ import annotations
+
+from aiohttp import ClientSession
+from ..typing import AsyncResult, Messages
+from .base_provider import AsyncGeneratorProvider, ProviderModelMixin
+from .helper import format_prompt
+
+
+class Editee(AsyncGeneratorProvider, ProviderModelMixin):
+ label = "Editee"
+ url = "https://editee.com"
+ api_endpoint = "https://editee.com/submit/chatgptfree"
+ working = True
+ supports_stream = True
+ supports_system_message = True
+ supports_message_history = True
+
+ default_model = 'claude'
+ models = ['claude', 'gpt4', 'gemini' 'mistrallarge']
+
+ model_aliases = {
+ "claude-3.5-sonnet": "claude",
+ "gpt-4o": "gpt4",
+ "gemini-pro": "gemini",
+ "mistral-large": "mistrallarge",
+ }
+
+ @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,
+ proxy: str = None,
+ **kwargs
+ ) -> AsyncResult:
+ model = cls.get_model(model)
+
+ headers = {
+ "Accept": "application/json, text/plain, */*",
+ "Accept-Language": "en-US,en;q=0.9",
+ "Cache-Control": "no-cache",
+ "Content-Type": "application/json",
+ "Origin": cls.url,
+ "Pragma": "no-cache",
+ "Priority": "u=1, i",
+ "Referer": f"{cls.url}/chat-gpt",
+ "Sec-CH-UA": '"Chromium";v="129", "Not=A?Brand";v="8"',
+ "Sec-CH-UA-Mobile": '?0',
+ "Sec-CH-UA-Platform": '"Linux"',
+ "Sec-Fetch-Dest": 'empty',
+ "Sec-Fetch-Mode": 'cors',
+ "Sec-Fetch-Site": 'same-origin',
+ "User-Agent": 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36',
+ "X-Requested-With": 'XMLHttpRequest',
+ }
+
+ async with ClientSession(headers=headers) as session:
+ prompt = format_prompt(messages)
+ data = {
+ "user_input": prompt,
+ "context": " ",
+ "template_id": "",
+ "selected_model": model
+ }
+ async with session.post(cls.api_endpoint, json=data, proxy=proxy) as response:
+ response.raise_for_status()
+ response_data = await response.json()
+ yield response_data['text']
diff --git a/g4f/Provider/FlowGpt.py b/g4f/Provider/FlowGpt.py
index d823a7ab..1a45997b 100644
--- a/g4f/Provider/FlowGpt.py
+++ b/g4f/Provider/FlowGpt.py
@@ -12,8 +12,7 @@ from ..requests.raise_for_status import raise_for_status
class FlowGpt(AsyncGeneratorProvider, ProviderModelMixin):
url = "https://flowgpt.com/chat"
- working = True
- supports_gpt_35_turbo = True
+ working = False
supports_message_history = True
supports_system_message = True
default_model = "gpt-3.5-turbo"
diff --git a/g4f/Provider/FreeNetfly.py b/g4f/Provider/FreeNetfly.py
index d0543176..ada5d51a 100644
--- a/g4f/Provider/FreeNetfly.py
+++ b/g4f/Provider/FreeNetfly.py
@@ -13,8 +13,6 @@ class FreeNetfly(AsyncGeneratorProvider, ProviderModelMixin):
url = "https://free.netfly.top"
api_endpoint = "/api/openai/v1/chat/completions"
working = True
- supports_gpt_35_turbo = True
- supports_gpt_4 = True
default_model = 'gpt-3.5-turbo'
models = [
'gpt-3.5-turbo',
diff --git a/g4f/Provider/GPROChat.py b/g4f/Provider/GPROChat.py
new file mode 100644
index 00000000..a33c9571
--- /dev/null
+++ b/g4f/Provider/GPROChat.py
@@ -0,0 +1,67 @@
+from __future__ import annotations
+import hashlib
+import time
+from aiohttp import ClientSession
+from ..typing import AsyncResult, Messages
+from .base_provider import AsyncGeneratorProvider, ProviderModelMixin
+from .helper import format_prompt
+
+class GPROChat(AsyncGeneratorProvider, ProviderModelMixin):
+ label = "GPROChat"
+ url = "https://gprochat.com"
+ api_endpoint = "https://gprochat.com/api/generate"
+ working = True
+ supports_stream = True
+ supports_message_history = True
+ default_model = 'gemini-pro'
+
+ @staticmethod
+ def generate_signature(timestamp: int, message: str) -> str:
+ secret_key = "2BC120D4-BB36-1B60-26DE-DB630472A3D8"
+ hash_input = f"{timestamp}:{message}:{secret_key}"
+ signature = hashlib.sha256(hash_input.encode('utf-8')).hexdigest()
+ return signature
+
+ @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,
+ proxy: str = None,
+ **kwargs
+ ) -> AsyncResult:
+ model = cls.get_model(model)
+ timestamp = int(time.time() * 1000)
+ prompt = format_prompt(messages)
+ sign = cls.generate_signature(timestamp, prompt)
+
+ headers = {
+ "accept": "*/*",
+ "origin": cls.url,
+ "referer": f"{cls.url}/",
+ "user-agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36",
+ "content-type": "text/plain;charset=UTF-8"
+ }
+
+ data = {
+ "messages": [{"role": "user", "parts": [{"text": prompt}]}],
+ "time": timestamp,
+ "pass": None,
+ "sign": sign
+ }
+
+ async with ClientSession(headers=headers) as session:
+ async with session.post(cls.api_endpoint, json=data, proxy=proxy) as response:
+ response.raise_for_status()
+ async for chunk in response.content.iter_any():
+ if chunk:
+ yield chunk.decode()
diff --git a/g4f/Provider/GeminiPro.py b/g4f/Provider/GeminiPro.py
index b225c26c..06bf69ee 100644
--- a/g4f/Provider/GeminiPro.py
+++ b/g4f/Provider/GeminiPro.py
@@ -54,6 +54,7 @@ class GeminiPro(AsyncGeneratorProvider, ProviderModelMixin):
"parts": [{"text": message["content"]}]
}
for message in messages
+ if message["role"] != "system"
]
if image is not None:
image = to_bytes(image)
@@ -73,6 +74,13 @@ class GeminiPro(AsyncGeneratorProvider, ProviderModelMixin):
"topK": kwargs.get("top_k"),
}
}
+ system_prompt = "\n".join(
+ message["content"]
+ for message in messages
+ if message["role"] == "system"
+ )
+ if system_prompt:
+ data["system_instruction"] = {"parts": {"text": system_prompt}}
async with session.post(url, params=params, json=data) as response:
if not response.ok:
data = await response.json()
diff --git a/g4f/Provider/GizAI.py b/g4f/Provider/GizAI.py
new file mode 100644
index 00000000..127edc9e
--- /dev/null
+++ b/g4f/Provider/GizAI.py
@@ -0,0 +1,151 @@
+from __future__ import annotations
+
+import json
+from aiohttp import ClientSession
+
+from ..typing import AsyncResult, Messages
+from ..image import ImageResponse
+from .base_provider import AsyncGeneratorProvider, ProviderModelMixin
+from .helper import format_prompt
+
+class GizAI(AsyncGeneratorProvider, ProviderModelMixin):
+ url = "https://app.giz.ai/assistant/"
+ api_endpoint = "https://app.giz.ai/api/data/users/inferenceServer.infer"
+ working = True
+
+ supports_system_message = True
+ supports_message_history = True
+
+ # Chat models
+ default_model = 'chat-gemini-flash'
+ chat_models = [
+ default_model,
+ 'chat-gemini-pro',
+ 'chat-gpt4m',
+ 'chat-gpt4',
+ 'claude-sonnet',
+ 'claude-haiku',
+ 'llama-3-70b',
+ 'llama-3-8b',
+ 'mistral-large',
+ 'chat-o1-mini'
+ ]
+
+ # Image models
+ image_models = [
+ 'flux1',
+ 'sdxl',
+ 'sd',
+ 'sd35',
+ ]
+
+ models = [*chat_models, *image_models]
+
+ model_aliases = {
+ # Chat model aliases
+ "gemini-flash": "chat-gemini-flash",
+ "gemini-pro": "chat-gemini-pro",
+ "gpt-4o-mini": "chat-gpt4m",
+ "gpt-4o": "chat-gpt4",
+ "claude-3.5-sonnet": "claude-sonnet",
+ "claude-3-haiku": "claude-haiku",
+ "llama-3.1-70b": "llama-3-70b",
+ "llama-3.1-8b": "llama-3-8b",
+ "o1-mini": "chat-o1-mini",
+ # Image model aliases
+ "sd-1.5": "sd",
+ "sd-3.5": "sd35",
+ "flux-schnell": "flux1",
+ }
+
+ @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 is_image_model(cls, model: str) -> bool:
+ return model in cls.image_models
+
+ @classmethod
+ async def create_async_generator(
+ cls,
+ model: str,
+ messages: Messages,
+ proxy: str = None,
+ **kwargs
+ ) -> AsyncResult:
+ model = cls.get_model(model)
+
+ headers = {
+ 'Accept': 'application/json, text/plain, */*',
+ 'Accept-Language': 'en-US,en;q=0.9',
+ 'Cache-Control': 'no-cache',
+ 'Connection': 'keep-alive',
+ 'Content-Type': 'application/json',
+ 'Origin': 'https://app.giz.ai',
+ 'Pragma': 'no-cache',
+ 'Sec-Fetch-Dest': 'empty',
+ 'Sec-Fetch-Mode': 'cors',
+ 'Sec-Fetch-Site': 'same-origin',
+ 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36',
+ 'sec-ch-ua': '"Not?A_Brand";v="99", "Chromium";v="130"',
+ 'sec-ch-ua-mobile': '?0',
+ 'sec-ch-ua-platform': '"Linux"'
+ }
+
+ async with ClientSession() as session:
+ if cls.is_image_model(model):
+ # Image generation
+ prompt = messages[-1]["content"]
+ data = {
+ "model": model,
+ "input": {
+ "width": "1024",
+ "height": "1024",
+ "steps": 4,
+ "output_format": "webp",
+ "batch_size": 1,
+ "mode": "plan",
+ "prompt": prompt
+ }
+ }
+ async with session.post(
+ cls.api_endpoint,
+ headers=headers,
+ data=json.dumps(data),
+ proxy=proxy
+ ) as response:
+ response.raise_for_status()
+ response_data = await response.json()
+ if response_data.get('status') == 'completed' and response_data.get('output'):
+ for url in response_data['output']:
+ yield ImageResponse(images=url, alt="Generated Image")
+ else:
+ # Chat completion
+ data = {
+ "model": model,
+ "input": {
+ "messages": [
+ {
+ "type": "human",
+ "content": format_prompt(messages)
+ }
+ ],
+ "mode": "plan"
+ },
+ "noStream": True
+ }
+ async with session.post(
+ cls.api_endpoint,
+ headers=headers,
+ data=json.dumps(data),
+ proxy=proxy
+ ) as response:
+ response.raise_for_status()
+ result = await response.json()
+ yield result.get('output', '')
diff --git a/g4f/Provider/GptTalkRu.py b/g4f/Provider/GptTalkRu.py
deleted file mode 100644
index 6a59484f..00000000
--- a/g4f/Provider/GptTalkRu.py
+++ /dev/null
@@ -1,59 +0,0 @@
-from __future__ import annotations
-
-from aiohttp import ClientSession, BaseConnector
-
-from ..typing import AsyncResult, Messages
-from .base_provider import AsyncGeneratorProvider
-from .helper import get_random_string, get_connector
-from ..requests import raise_for_status, get_args_from_browser, WebDriver
-from ..webdriver import has_seleniumwire
-from ..errors import MissingRequirementsError
-
-class GptTalkRu(AsyncGeneratorProvider):
- url = "https://gpttalk.ru"
- working = True
- supports_gpt_35_turbo = True
-
- @classmethod
- async def create_async_generator(
- cls,
- model: str,
- messages: Messages,
- proxy: str = None,
- connector: BaseConnector = None,
- webdriver: WebDriver = None,
- **kwargs
- ) -> AsyncResult:
- if not model:
- model = "gpt-3.5-turbo"
- if not has_seleniumwire:
- raise MissingRequirementsError('Install "selenium-wire" package')
- args = get_args_from_browser(f"{cls.url}", webdriver)
- args["headers"]["accept"] = "application/json, text/plain, */*"
- async with ClientSession(connector=get_connector(connector, proxy), **args) as session:
- async with session.get("https://gpttalk.ru/getToken") as response:
- await raise_for_status(response)
- public_key = (await response.json())["response"]["key"]["publicKey"]
- random_string = get_random_string(8)
- data = {
- "model": model,
- "modelType": 1,
- "prompt": messages,
- "responseType": "stream",
- "security": {
- "randomMessage": random_string,
- "shifrText": encrypt(public_key, random_string)
- }
- }
- async with session.post(f"{cls.url}/gpt2", json=data, proxy=proxy) as response:
- await raise_for_status(response)
- async for chunk in response.content.iter_any():
- yield chunk.decode(errors="ignore")
-
-def encrypt(public_key: str, value: str) -> str:
- from Crypto.Cipher import PKCS1_v1_5
- from Crypto.PublicKey import RSA
- import base64
- rsa_key = RSA.importKey(public_key)
- cipher = PKCS1_v1_5.new(rsa_key)
- return base64.b64encode(cipher.encrypt(value.encode())).decode() \ No newline at end of file
diff --git a/g4f/Provider/HuggingChat.py b/g4f/Provider/HuggingChat.py
index 06216ade..7ebbf570 100644
--- a/g4f/Provider/HuggingChat.py
+++ b/g4f/Provider/HuggingChat.py
@@ -1,6 +1,7 @@
from __future__ import annotations
-import json, requests, re
+import json
+import requests
from curl_cffi import requests as cf_reqs
from ..typing import CreateResult, Messages
@@ -16,19 +17,23 @@ class HuggingChat(AbstractProvider, ProviderModelMixin):
models = [
'meta-llama/Meta-Llama-3.1-70B-Instruct',
'CohereForAI/c4ai-command-r-plus-08-2024',
- 'mistralai/Mixtral-8x7B-Instruct-v0.1',
- 'NousResearch/Nous-Hermes-2-Mixtral-8x7B-DPO',
- 'mistralai/Mistral-7B-Instruct-v0.3',
- 'microsoft/Phi-3-mini-4k-instruct',
+ 'Qwen/Qwen2.5-72B-Instruct',
+ 'nvidia/Llama-3.1-Nemotron-70B-Instruct-HF',
+ 'meta-llama/Llama-3.2-11B-Vision-Instruct',
+ 'NousResearch/Hermes-3-Llama-3.1-8B',
+ 'mistralai/Mistral-Nemo-Instruct-2407',
+ 'microsoft/Phi-3.5-mini-instruct',
]
model_aliases = {
"llama-3.1-70b": "meta-llama/Meta-Llama-3.1-70B-Instruct",
"command-r-plus": "CohereForAI/c4ai-command-r-plus-08-2024",
- "mixtral-8x7b": "mistralai/Mixtral-8x7B-Instruct-v0.1",
- "mixtral-8x7b-dpo": "NousResearch/Nous-Hermes-2-Mixtral-8x7B-DPO",
- "mistral-7b": "mistralai/Mistral-7B-Instruct-v0.3",
- "phi-3-mini-4k": "microsoft/Phi-3-mini-4k-instruct",
+ "qwen-2-72b": "Qwen/Qwen2.5-72B-Instruct",
+ "nemotron-70b": "nvidia/Llama-3.1-Nemotron-70B-Instruct-HF",
+ "llama-3.2-11b": "meta-llama/Llama-3.2-11B-Vision-Instruct",
+ "hermes-3": "NousResearch/Hermes-3-Llama-3.1-8B",
+ "mistral-nemo": "mistralai/Mistral-Nemo-Instruct-2407",
+ "phi-3.5-mini": "microsoft/Phi-3.5-mini-instruct",
}
@classmethod
@@ -69,17 +74,18 @@ class HuggingChat(AbstractProvider, ProviderModelMixin):
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36',
}
- print(model)
json_data = {
'model': model,
}
response = session.post('https://huggingface.co/chat/conversation', json=json_data)
- conversationId = response.json()['conversationId']
+ if response.status_code != 200:
+ raise RuntimeError(f"Request failed with status code: {response.status_code}, response: {response.text}")
- response = session.get(f'https://huggingface.co/chat/conversation/{conversationId}/__data.json?x-sveltekit-invalidated=11',)
+ conversationId = response.json().get('conversationId')
+ response = session.get(f'https://huggingface.co/chat/conversation/{conversationId}/__data.json?x-sveltekit-invalidated=11')
- data: list = (response.json())["nodes"][1]["data"]
+ data: list = response.json()["nodes"][1]["data"]
keys: list[int] = data[data[0]["messages"]]
message_keys: dict = data[keys[0]]
messageId: str = data[message_keys["id"]]
@@ -120,22 +126,26 @@ class HuggingChat(AbstractProvider, ProviderModelMixin):
files=files,
)
- first_token = True
+ full_response = ""
for line in response.iter_lines():
- line = json.loads(line)
+ if not line:
+ continue
+ try:
+ line = json.loads(line)
+ except json.JSONDecodeError as e:
+ print(f"Failed to decode JSON: {line}, error: {e}")
+ continue
if "type" not in line:
raise RuntimeError(f"Response: {line}")
elif line["type"] == "stream":
- token = line["token"]
- if first_token:
- token = token.lstrip().replace('\u0000', '')
- first_token = False
- else:
- token = token.replace('\u0000', '')
-
- yield token
+ token = line["token"].replace('\u0000', '')
+ full_response += token
elif line["type"] == "finalAnswer":
break
+
+ full_response = full_response.replace('<|im_end|', '').replace('\u0000', '').strip()
+
+ yield full_response
diff --git a/g4f/Provider/Koala.py b/g4f/Provider/Koala.py
index 14e533df..0dd76b71 100644
--- a/g4f/Provider/Koala.py
+++ b/g4f/Provider/Koala.py
@@ -14,7 +14,6 @@ class Koala(AsyncGeneratorProvider, ProviderModelMixin):
api_endpoint = "https://koala.sh/api/gpt/"
working = True
supports_message_history = True
- supports_gpt_4 = True
default_model = 'gpt-4o-mini'
@classmethod
diff --git a/g4f/Provider/Liaobots.py b/g4f/Provider/Liaobots.py
index 8a9f46b1..56f765de 100644
--- a/g4f/Provider/Liaobots.py
+++ b/g4f/Provider/Liaobots.py
@@ -9,6 +9,15 @@ from .helper import get_connector
from ..requests import raise_for_status
models = {
+ "gpt-3.5-turbo": {
+ "id": "gpt-3.5-turbo",
+ "name": "GPT-3.5-Turbo",
+ "model": "ChatGPT",
+ "provider": "OpenAI",
+ "maxLength": 48000,
+ "tokenLimit": 14000,
+ "context": "16K",
+ },
"gpt-4o-mini-free": {
"id": "gpt-4o-mini-free",
"name": "GPT-4o-Mini-Free",
@@ -36,32 +45,41 @@ models = {
"tokenLimit": 7800,
"context": "8K",
},
- "gpt-4-turbo-2024-04-09": {
- "id": "gpt-4-turbo-2024-04-09",
- "name": "GPT-4-Turbo",
+ "gpt-4o-2024-08-06": {
+ "id": "gpt-4o-2024-08-06",
+ "name": "GPT-4o",
"model": "ChatGPT",
"provider": "OpenAI",
"maxLength": 260000,
"tokenLimit": 126000,
"context": "128K",
},
- "gpt-4o-2024-08-06": {
- "id": "gpt-4o-2024-08-06",
- "name": "GPT-4o",
+ "gpt-4-turbo-2024-04-09": {
+ "id": "gpt-4-turbo-2024-04-09",
+ "name": "GPT-4-Turbo",
"model": "ChatGPT",
"provider": "OpenAI",
"maxLength": 260000,
"tokenLimit": 126000,
"context": "128K",
},
- "gpt-4-0613": {
- "id": "gpt-4-0613",
- "name": "GPT-4-0613",
- "model": "ChatGPT",
- "provider": "OpenAI",
- "maxLength": 32000,
- "tokenLimit": 7600,
- "context": "8K",
+ "grok-2": {
+ "id": "grok-2",
+ "name": "Grok-2",
+ "model": "Grok",
+ "provider": "x.ai",
+ "maxLength": 400000,
+ "tokenLimit": 100000,
+ "context": "100K",
+ },
+ "grok-2-mini": {
+ "id": "grok-2-mini",
+ "name": "Grok-2-mini",
+ "model": "Grok",
+ "provider": "x.ai",
+ "maxLength": 400000,
+ "tokenLimit": 100000,
+ "context": "100K",
},
"claude-3-opus-20240229": {
"id": "claude-3-opus-20240229",
@@ -90,18 +108,18 @@ models = {
"tokenLimit": 200000,
"context": "200K",
},
- "claude-3-sonnet-20240229": {
- "id": "claude-3-sonnet-20240229",
- "name": "Claude-3-Sonnet",
+ "claude-3-5-sonnet-20240620": {
+ "id": "claude-3-5-sonnet-20240620",
+ "name": "Claude-3.5-Sonnet",
"model": "Claude",
"provider": "Anthropic",
"maxLength": 800000,
"tokenLimit": 200000,
"context": "200K",
},
- "claude-3-5-sonnet-20240620": {
- "id": "claude-3-5-sonnet-20240620",
- "name": "Claude-3.5-Sonnet",
+ "claude-3-sonnet-20240229": {
+ "id": "claude-3-sonnet-20240229",
+ "name": "Claude-3-Sonnet",
"model": "Claude",
"provider": "Anthropic",
"maxLength": 800000,
@@ -126,17 +144,8 @@ models = {
"tokenLimit": 200000,
"context": "200K",
},
- "gemini-1.0-pro-latest": {
- "id": "gemini-1.0-pro-latest",
- "name": "Gemini-Pro",
- "model": "Gemini",
- "provider": "Google",
- "maxLength": 120000,
- "tokenLimit": 30000,
- "context": "32K",
- },
- "gemini-1.5-flash-latest": {
- "id": "gemini-1.5-flash-latest",
+ "gemini-1.5-flash-002": {
+ "id": "gemini-1.5-flash-002",
"name": "Gemini-1.5-Flash-1M",
"model": "Gemini",
"provider": "Google",
@@ -144,8 +153,8 @@ models = {
"tokenLimit": 1000000,
"context": "1024K",
},
- "gemini-1.5-pro-latest": {
- "id": "gemini-1.5-pro-latest",
+ "gemini-1.5-pro-002": {
+ "id": "gemini-1.5-pro-002",
"name": "Gemini-1.5-Pro-1M",
"model": "Gemini",
"provider": "Google",
@@ -161,28 +170,27 @@ class Liaobots(AsyncGeneratorProvider, ProviderModelMixin):
working = True
supports_message_history = True
supports_system_message = True
- supports_gpt_4 = True
- default_model = "gpt-4o"
+ default_model = "gpt-3.5-turbo"
models = list(models.keys())
model_aliases = {
"gpt-4o-mini": "gpt-4o-mini-free",
"gpt-4o": "gpt-4o-free",
- "gpt-4-turbo": "gpt-4-turbo-2024-04-09",
"gpt-4o": "gpt-4o-2024-08-06",
+
+ "gpt-4-turbo": "gpt-4-turbo-2024-04-09",
"gpt-4": "gpt-4-0613",
"claude-3-opus": "claude-3-opus-20240229",
"claude-3-opus": "claude-3-opus-20240229-aws",
"claude-3-opus": "claude-3-opus-20240229-gcp",
"claude-3-sonnet": "claude-3-sonnet-20240229",
- "claude-3-5-sonnet": "claude-3-5-sonnet-20240620",
+ "claude-3.5-sonnet": "claude-3-5-sonnet-20240620",
"claude-3-haiku": "claude-3-haiku-20240307",
"claude-2.1": "claude-2.1",
- "gemini-pro": "gemini-1.0-pro-latest",
- "gemini-flash": "gemini-1.5-flash-latest",
- "gemini-pro": "gemini-1.5-pro-latest",
+ "gemini-flash": "gemini-1.5-flash-002",
+ "gemini-pro": "gemini-1.5-pro-002",
}
_auth_code = ""
diff --git a/g4f/Provider/LiteIcoding.py b/g4f/Provider/LiteIcoding.py
deleted file mode 100644
index 69294a57..00000000
--- a/g4f/Provider/LiteIcoding.py
+++ /dev/null
@@ -1,113 +0,0 @@
-from __future__ import annotations
-
-from aiohttp import ClientSession, ClientResponseError
-import re
-from ..typing import AsyncResult, Messages
-from .base_provider import AsyncGeneratorProvider, ProviderModelMixin
-from .helper import format_prompt
-
-
-class LiteIcoding(AsyncGeneratorProvider, ProviderModelMixin):
- url = "https://lite.icoding.ink"
- api_endpoint = "/api/v1/gpt/message"
- working = True
- supports_gpt_4 = True
- default_model = "gpt-4o"
- models = [
- 'gpt-4o',
- 'gpt-4-turbo',
- 'claude-3',
- 'claude-3.5',
- 'gemini-1.5',
- ]
-
- @classmethod
- async def create_async_generator(
- cls,
- model: str,
- messages: Messages,
- proxy: str = None,
- **kwargs
- ) -> AsyncResult:
- headers = {
- "Accept": "*/*",
- "Accept-Language": "en-US,en;q=0.9",
- "Authorization": "Bearer aa3020ee873e40cb8b3f515a0708ebc4",
- "Connection": "keep-alive",
- "Content-Type": "application/json;charset=utf-8",
- "DNT": "1",
- "Origin": cls.url,
- "Referer": f"{cls.url}/",
- "Sec-Fetch-Dest": "empty",
- "Sec-Fetch-Mode": "cors",
- "Sec-Fetch-Site": "same-origin",
- "User-Agent": (
- "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) "
- "Chrome/126.0.0.0 Safari/537.36"
- ),
- "sec-ch-ua": '"Not/A)Brand";v="8", "Chromium";v="126"',
- "sec-ch-ua-mobile": "?0",
- "sec-ch-ua-platform": '"Linux"',
- }
-
- data = {
- "model": model,
- "chatId": "-1",
- "messages": [
- {
- "role": msg["role"],
- "content": msg["content"],
- "time": msg.get("time", ""),
- "attachments": msg.get("attachments", []),
- }
- for msg in messages
- ],
- "plugins": [],
- "systemPrompt": "",
- "temperature": 0.5,
- }
-
- async with ClientSession(headers=headers) as session:
- try:
- async with session.post(
- f"{cls.url}{cls.api_endpoint}", json=data, proxy=proxy
- ) as response:
- response.raise_for_status()
- buffer = ""
- full_response = ""
- def decode_content(data):
- bytes_array = bytes([int(b, 16) ^ 255 for b in data.split()])
- return bytes_array.decode('utf-8')
- async for chunk in response.content.iter_any():
- if chunk:
- buffer += chunk.decode()
- while "\n\n" in buffer:
- part, buffer = buffer.split("\n\n", 1)
- if part.startswith("data: "):
- content = part[6:].strip()
- if content and content != "[DONE]":
- content = content.strip('"')
- # Decoding each content block
- decoded_content = decode_content(content)
- full_response += decoded_content
- full_response = (
- full_response.replace('""', '') # Handle double quotes
- .replace('" "', ' ') # Handle space within quotes
- .replace("\\n\\n", "\n\n")
- .replace("\\n", "\n")
- .replace('\\"', '"')
- .strip()
- )
- # Add filter to remove unwanted text
- filtered_response = re.sub(r'\n---\n.*', '', full_response, flags=re.DOTALL)
- # Remove extra quotes at the beginning and end
- cleaned_response = filtered_response.strip().strip('"')
- yield cleaned_response
-
- except ClientResponseError as e:
- raise RuntimeError(
- f"ClientResponseError {e.status}: {e.message}, url={e.request_info.url}, data={data}"
- ) from e
-
- except Exception as e:
- raise RuntimeError(f"Unexpected error: {str(e)}") from e
diff --git a/g4f/Provider/MagickPen.py b/g4f/Provider/MagickPen.py
index eab70536..7f1751dd 100644
--- a/g4f/Provider/MagickPen.py
+++ b/g4f/Provider/MagickPen.py
@@ -1,72 +1,53 @@
from __future__ import annotations
+from aiohttp import ClientSession
+import hashlib
import time
import random
-import hashlib
import re
-from aiohttp import ClientSession
-
+import json
from ..typing import AsyncResult, Messages
from .base_provider import AsyncGeneratorProvider, ProviderModelMixin
from .helper import format_prompt
class MagickPen(AsyncGeneratorProvider, ProviderModelMixin):
url = "https://magickpen.com"
- api_endpoint_free = "https://api.magickpen.com/chat/free"
- api_endpoint_ask = "https://api.magickpen.com/ask"
+ api_endpoint = "https://api.magickpen.com/ask"
working = True
- supports_gpt_4 = True
- supports_stream = False
-
- default_model = 'free'
- models = ['free', 'ask']
+ supports_stream = True
+ supports_system_message = True
+ supports_message_history = True
- model_aliases = {
- "gpt-4o-mini": "free",
- "gpt-4o-mini": "ask",
- }
-
- @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
+ default_model = 'gpt-4o-mini'
+ models = ['gpt-4o-mini']
@classmethod
- async def get_secrets(cls):
- url = 'https://magickpen.com/_nuxt/02c76dc.js'
+ async def fetch_api_credentials(cls) -> tuple:
+ url = "https://magickpen.com/_nuxt/bf709a9ce19f14e18116.js"
async with ClientSession() as session:
async with session.get(url) as response:
- if response.status == 200:
- text = await response.text()
- x_api_secret_match = re.search(r'"X-API-Secret":"([^"]+)"', text)
- secret_match = re.search(r'secret:\s*"([^"]+)"', text)
-
- x_api_secret = x_api_secret_match.group(1) if x_api_secret_match else None
- secret = secret_match.group(1) if secret_match else None
-
- # Generate timestamp and nonce dynamically
- timestamp = str(int(time.time() * 1000))
- nonce = str(random.random())
-
- # Generate signature
- signature_parts = ["TGDBU9zCgM", timestamp, nonce]
- signature_string = "".join(sorted(signature_parts))
- signature = hashlib.md5(signature_string.encode()).hexdigest()
-
- return {
- 'X-API-Secret': x_api_secret,
- 'signature': signature,
- 'timestamp': timestamp,
- 'nonce': nonce,
- 'secret': secret
- }
- else:
- print(f"Error while fetching the file: {response.status}")
- return None
+ text = await response.text()
+
+ pattern = r'"X-API-Secret":"(\w+)"'
+ match = re.search(pattern, text)
+ X_API_SECRET = match.group(1) if match else None
+
+ timestamp = str(int(time.time() * 1000))
+ nonce = str(random.random())
+
+ s = ["TGDBU9zCgM", timestamp, nonce]
+ s.sort()
+ signature_string = ''.join(s)
+ signature = hashlib.md5(signature_string.encode()).hexdigest()
+
+ pattern = r'secret:"(\w+)"'
+ match = re.search(pattern, text)
+ secret = match.group(1) if match else None
+
+ if X_API_SECRET and timestamp and nonce and secret:
+ return X_API_SECRET, signature, timestamp, nonce, secret
+ else:
+ raise Exception("Unable to extract all the necessary data from the JavaScript file.")
@classmethod
async def create_async_generator(
@@ -77,54 +58,30 @@ class MagickPen(AsyncGeneratorProvider, ProviderModelMixin):
**kwargs
) -> AsyncResult:
model = cls.get_model(model)
+ X_API_SECRET, signature, timestamp, nonce, secret = await cls.fetch_api_credentials()
- secrets = await cls.get_secrets()
- if not secrets:
- raise Exception("Failed to obtain necessary secrets")
-
headers = {
- "accept": "application/json, text/plain, */*",
- "accept-language": "en-US,en;q=0.9",
- "cache-control": "no-cache",
- "content-type": "application/json",
- "nonce": secrets['nonce'],
- "origin": "https://magickpen.com",
- "pragma": "no-cache",
- "priority": "u=1, i",
- "referer": "https://magickpen.com/",
- "sec-ch-ua": '"Chromium";v="127", "Not)A;Brand";v="99"',
- "sec-ch-ua-mobile": "?0",
- "sec-ch-ua-platform": '"Linux"',
- "sec-fetch-dest": "empty",
- "sec-fetch-mode": "cors",
- "sec-fetch-site": "same-site",
- "secret": secrets['secret'],
- "signature": secrets['signature'],
- "timestamp": secrets['timestamp'],
- "user-agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36",
- "x-api-secret": secrets['X-API-Secret']
+ 'accept': 'application/json, text/plain, */*',
+ 'accept-language': 'en-US,en;q=0.9',
+ 'content-type': 'application/json',
+ 'nonce': nonce,
+ 'origin': cls.url,
+ 'referer': f"{cls.url}/",
+ 'secret': secret,
+ 'signature': signature,
+ 'timestamp': timestamp,
+ 'x-api-secret': X_API_SECRET,
}
async with ClientSession(headers=headers) as session:
- if model == 'free':
- data = {
- "history": [{"role": "user", "content": format_prompt(messages)}]
- }
- async with session.post(cls.api_endpoint_free, json=data, proxy=proxy) as response:
- response.raise_for_status()
- result = await response.text()
- yield result
-
- elif model == 'ask':
- data = {
- "query": format_prompt(messages),
- "plan": "Pay as you go"
- }
- async with session.post(cls.api_endpoint_ask, json=data, proxy=proxy) as response:
- response.raise_for_status()
- async for chunk in response.content:
- if chunk:
- yield chunk.decode()
-
- else:
- raise ValueError(f"Unknown model: {model}")
+ prompt = format_prompt(messages)
+ payload = {
+ 'query': prompt,
+ 'turnstileResponse': '',
+ 'action': 'verify'
+ }
+ async with session.post(cls.api_endpoint, json=payload, proxy=proxy) as response:
+ response.raise_for_status()
+ async for chunk in response.content:
+ if chunk:
+ yield chunk.decode()
diff --git a/g4f/Provider/Nexra.py b/g4f/Provider/Nexra.py
deleted file mode 100644
index b2b83837..00000000
--- a/g4f/Provider/Nexra.py
+++ /dev/null
@@ -1,116 +0,0 @@
-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
-from ..image import ImageResponse
-
-class Nexra(AsyncGeneratorProvider, ProviderModelMixin):
- url = "https://nexra.aryahcr.cc"
- chat_api_endpoint = "https://nexra.aryahcr.cc/api/chat/gpt"
- image_api_endpoint = "https://nexra.aryahcr.cc/api/image/complements"
- working = True
- supports_gpt_35_turbo = True
- supports_gpt_4 = True
- supports_system_message = True
- supports_message_history = True
-
- default_model = 'gpt-3.5-turbo'
- text_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',
- ]
- image_models = ['dalle', 'dalle2', 'dalle-mini', 'emi']
- models = [*text_models, *image_models]
-
- model_aliases = {
- "gpt-4": "gpt-4-0613",
- "gpt-4": "gpt-4-32k",
- "gpt-4": "gpt-4-0314",
- "gpt-4": "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": "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",
-
- "dalle-2": "dalle2",
- }
-
- @classmethod
- def get_model(cls, model: str) -> str:
- if model in cls.text_models or model in cls.image_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,
- proxy: str = None,
- **kwargs
- ) -> AsyncResult:
- model = cls.get_model(model)
-
- headers = {
- "Content-Type": "application/json",
- }
-
- async with ClientSession(headers=headers) as session:
- if model in cls.image_models:
- # Image generation
- prompt = messages[-1]['content'] if messages else ""
- data = {
- "prompt": prompt,
- "model": model,
- "response": "url"
- }
- async with session.post(cls.image_api_endpoint, json=data, proxy=proxy) as response:
- response.raise_for_status()
- result = await response.text()
- result_json = json.loads(result.strip('_'))
- image_url = result_json['images'][0] if result_json['images'] else None
-
- if image_url:
- yield ImageResponse(images=image_url, alt=prompt)
- else:
- # Text completion
- data = {
- "messages": messages,
- "prompt": format_prompt(messages),
- "model": model,
- "markdown": False
- }
- async with session.post(cls.chat_api_endpoint, json=data, proxy=proxy) as response:
- response.raise_for_status()
- result = await response.text()
-
- try:
- json_response = json.loads(result)
- gpt_response = json_response.get('gpt', '')
- yield gpt_response
- except json.JSONDecodeError:
- yield result
diff --git a/g4f/Provider/Ollama.py b/g4f/Provider/Ollama.py
index a44aaacd..f9116541 100644
--- a/g4f/Provider/Ollama.py
+++ b/g4f/Provider/Ollama.py
@@ -1,6 +1,7 @@
from __future__ import annotations
import requests
+import os
from .needs_auth.Openai import Openai
from ..typing import AsyncResult, Messages
@@ -14,9 +15,11 @@ class Ollama(Openai):
@classmethod
def get_models(cls):
if not cls.models:
- url = 'http://127.0.0.1:11434/api/tags'
+ host = os.getenv("OLLAMA_HOST", "127.0.0.1")
+ port = os.getenv("OLLAMA_PORT", "11434")
+ url = f"http://{host}:{port}/api/tags"
models = requests.get(url).json()["models"]
- cls.models = [model['name'] for model in models]
+ cls.models = [model["name"] for model in models]
cls.default_model = cls.models[0]
return cls.models
@@ -25,9 +28,13 @@ class Ollama(Openai):
cls,
model: str,
messages: Messages,
- api_base: str = "http://localhost:11434/v1",
+ api_base: str = None,
**kwargs
) -> AsyncResult:
+ if not api_base:
+ host = os.getenv("OLLAMA_HOST", "localhost")
+ port = os.getenv("OLLAMA_PORT", "11434")
+ api_base: str = f"http://{host}:{port}/v1"
return super().create_async_generator(
model, messages, api_base=api_base, **kwargs
) \ No newline at end of file
diff --git a/g4f/Provider/PerplexityLabs.py b/g4f/Provider/PerplexityLabs.py
index ecb51f9b..b776e96a 100644
--- a/g4f/Provider/PerplexityLabs.py
+++ b/g4f/Provider/PerplexityLabs.py
@@ -24,10 +24,10 @@ class PerplexityLabs(AsyncGeneratorProvider, ProviderModelMixin):
]
model_aliases = {
- "llama-3.1-8b": "llama-3.1-sonar-large-128k-online",
- "llama-3.1-8b": "sonar-small-128k-online",
- "llama-3.1-8b": "llama-3.1-sonar-large-128k-chat",
- "llama-3.1-8b": "llama-3.1-sonar-small-128k-chat",
+ "sonar-online": "llama-3.1-sonar-large-128k-online",
+ "sonar-online": "sonar-small-128k-online",
+ "sonar-chat": "llama-3.1-sonar-large-128k-chat",
+ "sonar-chat": "llama-3.1-sonar-small-128k-chat",
"llama-3.1-8b": "llama-3.1-8b-instruct",
"llama-3.1-70b": "llama-3.1-70b-instruct",
}
diff --git a/g4f/Provider/Pi.py b/g4f/Provider/Pi.py
index e03830f4..266647ba 100644
--- a/g4f/Provider/Pi.py
+++ b/g4f/Provider/Pi.py
@@ -22,6 +22,7 @@ class Pi(AbstractProvider):
proxy: str = None,
timeout: int = 180,
conversation_id: str = None,
+ webdriver: WebDriver = None,
**kwargs
) -> CreateResult:
if cls._session is None:
diff --git a/g4f/Provider/Pizzagpt.py b/g4f/Provider/Pizzagpt.py
index 47cb135c..6513bd34 100644
--- a/g4f/Provider/Pizzagpt.py
+++ b/g4f/Provider/Pizzagpt.py
@@ -12,7 +12,6 @@ class Pizzagpt(AsyncGeneratorProvider, ProviderModelMixin):
url = "https://www.pizzagpt.it"
api_endpoint = "/api/chatx-completion"
working = True
- supports_gpt_4 = True
default_model = 'gpt-4o-mini'
@classmethod
diff --git a/g4f/Provider/Prodia.py b/g4f/Provider/Prodia.py
index dd87a34c..543a8b19 100644
--- a/g4f/Provider/Prodia.py
+++ b/g4f/Provider/Prodia.py
@@ -14,10 +14,10 @@ class Prodia(AsyncGeneratorProvider, ProviderModelMixin):
working = True
default_model = 'absolutereality_v181.safetensors [3d9d4d2b]'
- models = [
+ image_models = [
'3Guofeng3_v34.safetensors [50f420de]',
'absolutereality_V16.safetensors [37db0fc3]',
- 'absolutereality_v181.safetensors [3d9d4d2b]',
+ default_model,
'amIReal_V41.safetensors [0a8a2e61]',
'analog-diffusion-1.0.ckpt [9ca13f02]',
'aniverse_v30.safetensors [579e6f85]',
@@ -81,6 +81,7 @@ class Prodia(AsyncGeneratorProvider, ProviderModelMixin):
'timeless-1.0.ckpt [7c4971d4]',
'toonyou_beta6.safetensors [980f6b15]',
]
+ models = [*image_models]
@classmethod
def get_model(cls, model: str) -> str:
diff --git a/g4f/Provider/RubiksAI.py b/g4f/Provider/RubiksAI.py
new file mode 100644
index 00000000..7e76d558
--- /dev/null
+++ b/g4f/Provider/RubiksAI.py
@@ -0,0 +1,162 @@
+from __future__ import annotations
+
+import asyncio
+import aiohttp
+import random
+import string
+import json
+from urllib.parse import urlencode
+
+from aiohttp import ClientSession
+
+from ..typing import AsyncResult, Messages
+from .base_provider import AsyncGeneratorProvider, ProviderModelMixin
+from .helper import format_prompt
+
+
+class RubiksAI(AsyncGeneratorProvider, ProviderModelMixin):
+ label = "Rubiks AI"
+ url = "https://rubiks.ai"
+ api_endpoint = "https://rubiks.ai/search/api.php"
+ working = True
+ supports_stream = True
+ supports_system_message = True
+ supports_message_history = True
+
+ default_model = 'llama-3.1-70b-versatile'
+ models = [default_model, 'gpt-4o-mini']
+
+ model_aliases = {
+ "llama-3.1-70b": "llama-3.1-70b-versatile",
+ }
+
+ @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
+
+ @staticmethod
+ def generate_mid() -> str:
+ """
+ Generates a 'mid' string following the pattern:
+ 6 characters - 4 characters - 4 characters - 4 characters - 12 characters
+ Example: 0r7v7b-quw4-kdy3-rvdu-ekief6xbuuq4
+ """
+ parts = [
+ ''.join(random.choices(string.ascii_lowercase + string.digits, k=6)),
+ ''.join(random.choices(string.ascii_lowercase + string.digits, k=4)),
+ ''.join(random.choices(string.ascii_lowercase + string.digits, k=4)),
+ ''.join(random.choices(string.ascii_lowercase + string.digits, k=4)),
+ ''.join(random.choices(string.ascii_lowercase + string.digits, k=12))
+ ]
+ return '-'.join(parts)
+
+ @staticmethod
+ def create_referer(q: str, mid: str, model: str = '') -> str:
+ """
+ Creates a Referer URL with dynamic q and mid values, using urlencode for safe parameter encoding.
+ """
+ params = {'q': q, 'model': model, 'mid': mid}
+ encoded_params = urlencode(params)
+ return f'https://rubiks.ai/search/?{encoded_params}'
+
+ @classmethod
+ async def create_async_generator(
+ cls,
+ model: str,
+ messages: Messages,
+ proxy: str = None,
+ websearch: bool = False,
+ **kwargs
+ ) -> AsyncResult:
+ """
+ Creates an asynchronous generator that sends requests to the Rubiks AI API and yields the response.
+
+ Parameters:
+ - model (str): The model to use in the request.
+ - messages (Messages): The messages to send as a prompt.
+ - proxy (str, optional): Proxy URL, if needed.
+ - websearch (bool, optional): Indicates whether to include search sources in the response. Defaults to False.
+ """
+ model = cls.get_model(model)
+ prompt = format_prompt(messages)
+ q_value = prompt
+ mid_value = cls.generate_mid()
+ referer = cls.create_referer(q=q_value, mid=mid_value, model=model)
+
+ url = cls.api_endpoint
+ params = {
+ 'q': q_value,
+ 'model': model,
+ 'id': '',
+ 'mid': mid_value
+ }
+
+ headers = {
+ 'Accept': 'text/event-stream',
+ 'Accept-Language': 'en-US,en;q=0.9',
+ 'Cache-Control': 'no-cache',
+ 'Connection': 'keep-alive',
+ 'Pragma': 'no-cache',
+ 'Referer': referer,
+ 'Sec-Fetch-Dest': 'empty',
+ 'Sec-Fetch-Mode': 'cors',
+ 'Sec-Fetch-Site': 'same-origin',
+ 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36',
+ 'sec-ch-ua': '"Chromium";v="129", "Not=A?Brand";v="8"',
+ 'sec-ch-ua-mobile': '?0',
+ 'sec-ch-ua-platform': '"Linux"'
+ }
+
+ try:
+ timeout = aiohttp.ClientTimeout(total=None)
+ async with ClientSession(timeout=timeout) as session:
+ async with session.get(url, headers=headers, params=params, proxy=proxy) as response:
+ if response.status != 200:
+ yield f"Request ended with status code {response.status}"
+ return
+
+ assistant_text = ''
+ sources = []
+
+ async for line in response.content:
+ decoded_line = line.decode('utf-8').strip()
+ if not decoded_line.startswith('data: '):
+ continue
+ data = decoded_line[6:]
+ if data in ('[DONE]', '{"done": ""}'):
+ break
+ try:
+ json_data = json.loads(data)
+ except json.JSONDecodeError:
+ continue
+
+ if 'url' in json_data and 'title' in json_data:
+ if websearch:
+ sources.append({'title': json_data['title'], 'url': json_data['url']})
+
+ elif 'choices' in json_data:
+ for choice in json_data['choices']:
+ delta = choice.get('delta', {})
+ content = delta.get('content', '')
+ role = delta.get('role', '')
+ if role == 'assistant':
+ continue
+ assistant_text += content
+
+ if websearch and sources:
+ sources_text = '\n'.join([f"{i+1}. [{s['title']}]: {s['url']}" for i, s in enumerate(sources)])
+ assistant_text += f"\n\n**Source:**\n{sources_text}"
+
+ yield assistant_text
+
+ except asyncio.CancelledError:
+ yield "The request was cancelled."
+ except aiohttp.ClientError as e:
+ yield f"An error occurred during the request: {e}"
+ except Exception as e:
+ yield f"An unexpected error occurred: {e}"
diff --git a/g4f/Provider/Snova.py b/g4f/Provider/Snova.py
deleted file mode 100644
index 53d8f0bd..00000000
--- a/g4f/Provider/Snova.py
+++ /dev/null
@@ -1,131 +0,0 @@
-from __future__ import annotations
-
-import json
-from typing import AsyncGenerator
-
-from aiohttp import ClientSession
-
-from ..typing import AsyncResult, Messages
-from .base_provider import AsyncGeneratorProvider, ProviderModelMixin
-from .helper import format_prompt
-
-
-class Snova(AsyncGeneratorProvider, ProviderModelMixin):
- url = "https://fast.snova.ai"
- api_endpoint = "https://fast.snova.ai/api/completion"
- working = True
- supports_stream = True
- supports_system_message = True
- supports_message_history = True
-
- default_model = 'Meta-Llama-3.1-8B-Instruct'
- models = [
- 'Meta-Llama-3.1-8B-Instruct',
- 'Meta-Llama-3.1-70B-Instruct',
- 'Meta-Llama-3.1-405B-Instruct',
- 'Samba-CoE',
- 'ignos/Mistral-T5-7B-v1', # Error with the answer
- 'v1olet/v1olet_merged_dpo_7B',
- 'macadeliccc/WestLake-7B-v2-laser-truthy-dpo',
- ]
-
- model_aliases = {
- "llama-3.1-8b": "Meta-Llama-3.1-8B-Instruct",
- "llama-3.1-70b": "Meta-Llama-3.1-70B-Instruct",
- "llama-3.1-405b": "Meta-Llama-3.1-405B-Instruct",
-
- "mistral-7b": "ignos/Mistral-T5-7B-v1",
-
- "samba-coe-v0.1": "Samba-CoE",
- "v1olet-merged-7b": "v1olet/v1olet_merged_dpo_7B",
- "westlake-7b-v2": "macadeliccc/WestLake-7B-v2-laser-truthy-dpo",
- }
-
- @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,
- proxy: str = None,
- **kwargs
- ) -> AsyncGenerator[str, None]:
- model = cls.get_model(model)
-
- headers = {
- "accept": "text/event-stream",
- "accept-language": "en-US,en;q=0.9",
- "cache-control": "no-cache",
- "content-type": "application/json",
- "origin": cls.url,
- "pragma": "no-cache",
- "priority": "u=1, i",
- "referer": f"{cls.url}/",
- "sec-ch-ua": '"Chromium";v="127", "Not)A;Brand";v="99"',
- "sec-ch-ua-mobile": "?0",
- "sec-ch-ua-platform": '"Linux"',
- "sec-fetch-dest": "empty",
- "sec-fetch-mode": "cors",
- "sec-fetch-site": "same-origin",
- "user-agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36"
- }
- async with ClientSession(headers=headers) as session:
- data = {
- "body": {
- "messages": [
- {
- "role": "system",
- "content": "You are a helpful assistant."
- },
- {
- "role": "user",
- "content": format_prompt(messages),
- "id": "1-id",
- "ref": "1-ref",
- "revision": 1,
- "draft": False,
- "status": "done",
- "enableRealTimeChat": False,
- "meta": None
- }
- ],
- "max_tokens": 1000,
- "stop": ["<|eot_id|>"],
- "stream": True,
- "stream_options": {"include_usage": True},
- "model": model
- },
- "env_type": "tp16"
- }
- 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:
- line = line.decode().strip()
- if line.startswith("data: "):
- data = line[6:]
- if data == "[DONE]":
- break
- try:
- json_data = json.loads(data)
- choices = json_data.get("choices", [])
- if choices:
- delta = choices[0].get("delta", {})
- content = delta.get("content", "")
- full_response += content
- except json.JSONDecodeError:
- continue
- except Exception as e:
- print(f"Error processing chunk: {e}")
- print(f"Problematic data: {data}")
- continue
-
- yield full_response.strip()
diff --git a/g4f/Provider/TwitterBio.py b/g4f/Provider/TwitterBio.py
deleted file mode 100644
index c143e4ff..00000000
--- a/g4f/Provider/TwitterBio.py
+++ /dev/null
@@ -1,103 +0,0 @@
-from __future__ import annotations
-
-import json
-import re
-from aiohttp import ClientSession
-
-from ..typing import AsyncResult, Messages
-from .base_provider import AsyncGeneratorProvider, ProviderModelMixin
-from .helper import format_prompt
-
-class TwitterBio(AsyncGeneratorProvider, ProviderModelMixin):
- url = "https://www.twitterbio.io"
- api_endpoint_mistral = "https://www.twitterbio.io/api/mistral"
- api_endpoint_openai = "https://www.twitterbio.io/api/openai"
- working = True
- supports_gpt_35_turbo = True
-
- default_model = 'gpt-3.5-turbo'
- models = [
- 'mistralai/Mixtral-8x7B-Instruct-v0.1',
- 'gpt-3.5-turbo',
- ]
-
- model_aliases = {
- "mixtral-8x7b": "mistralai/Mixtral-8x7B-Instruct-v0.1",
- }
-
- @classmethod
- def get_model(cls, model: str) -> str:
- if model in cls.models:
- return model
- return cls.default_model
-
- @staticmethod
- def format_text(text: str) -> str:
- text = re.sub(r'\s+', ' ', text.strip())
- text = re.sub(r'\s+([,.!?])', r'\1', text)
- return text
-
- @classmethod
- async def create_async_generator(
- cls,
- model: str,
- messages: Messages,
- proxy: str = None,
- **kwargs
- ) -> AsyncResult:
- model = cls.get_model(model)
-
- headers = {
- "accept": "*/*",
- "accept-language": "en-US,en;q=0.9",
- "cache-control": "no-cache",
- "content-type": "application/json",
- "origin": cls.url,
- "pragma": "no-cache",
- "priority": "u=1, i",
- "referer": f"{cls.url}/",
- "sec-ch-ua": '"Chromium";v="127", "Not)A;Brand";v="99"',
- "sec-ch-ua-mobile": "?0",
- "sec-ch-ua-platform": '"Linux"',
- "sec-fetch-dest": "empty",
- "sec-fetch-mode": "cors",
- "sec-fetch-site": "same-origin",
- "user-agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36"
- }
- async with ClientSession(headers=headers) as session:
- prompt = format_prompt(messages)
- data = {
- "prompt": f'{prompt}.'
- }
-
- if model == 'mistralai/Mixtral-8x7B-Instruct-v0.1':
- api_endpoint = cls.api_endpoint_mistral
- elif model == 'gpt-3.5-turbo':
- api_endpoint = cls.api_endpoint_openai
- else:
- raise ValueError(f"Unsupported model: {model}")
-
- async with session.post(api_endpoint, json=data, proxy=proxy) as response:
- response.raise_for_status()
- buffer = ""
- async for line in response.content:
- line = line.decode('utf-8').strip()
- if line.startswith('data: '):
- try:
- json_data = json.loads(line[6:])
- if model == 'mistralai/Mixtral-8x7B-Instruct-v0.1':
- if 'choices' in json_data and len(json_data['choices']) > 0:
- text = json_data['choices'][0].get('text', '')
- if text:
- buffer += text
- elif model == 'gpt-3.5-turbo':
- text = json_data.get('text', '')
- if text:
- buffer += text
- except json.JSONDecodeError:
- continue
- elif line == 'data: [DONE]':
- break
-
- if buffer:
- yield cls.format_text(buffer)
diff --git a/g4f/Provider/Upstage.py b/g4f/Provider/Upstage.py
index e61a5af2..65409159 100644
--- a/g4f/Provider/Upstage.py
+++ b/g4f/Provider/Upstage.py
@@ -12,14 +12,15 @@ class Upstage(AsyncGeneratorProvider, ProviderModelMixin):
url = "https://console.upstage.ai/playground/chat"
api_endpoint = "https://ap-northeast-2.apistage.ai/v1/web/demo/chat/completions"
working = True
- default_model = 'upstage/solar-1-mini-chat'
+ default_model = 'solar-pro'
models = [
'upstage/solar-1-mini-chat',
'upstage/solar-1-mini-chat-ja',
+ 'solar-pro',
]
model_aliases = {
- "solar-1-mini": "upstage/solar-1-mini-chat",
- "solar-1-mini": "upstage/solar-1-mini-chat-ja",
+ "solar-mini": "upstage/solar-1-mini-chat",
+ "solar-mini": "upstage/solar-1-mini-chat-ja",
}
@classmethod
diff --git a/g4f/Provider/Vercel.py b/g4f/Provider/Vercel.py
deleted file mode 100644
index bd918396..00000000
--- a/g4f/Provider/Vercel.py
+++ /dev/null
@@ -1,104 +0,0 @@
-from __future__ import annotations
-
-import json, base64, requests, random, os
-
-try:
- import execjs
- has_requirements = True
-except ImportError:
- has_requirements = False
-
-from ..typing import Messages, CreateResult
-from .base_provider import AbstractProvider
-from ..requests import raise_for_status
-from ..errors import MissingRequirementsError
-
-class Vercel(AbstractProvider):
- url = 'https://chat.vercel.ai'
- working = True
- supports_message_history = True
- supports_system_message = True
- supports_gpt_35_turbo = True
- supports_stream = True
-
- @staticmethod
- def create_completion(
- model: str,
- messages: Messages,
- stream: bool,
- proxy: str = None,
- max_retries: int = 6,
- **kwargs
- ) -> CreateResult:
- if not has_requirements:
- raise MissingRequirementsError('Install "PyExecJS" package')
-
- headers = {
- 'authority': 'chat.vercel.ai',
- 'accept': '*/*',
- 'accept-language': 'en,fr-FR;q=0.9,fr;q=0.8,es-ES;q=0.7,es;q=0.6,en-US;q=0.5,am;q=0.4,de;q=0.3',
- 'cache-control': 'no-cache',
- 'content-type': 'application/json',
- 'custom-encoding': get_anti_bot_token(),
- 'origin': 'https://chat.vercel.ai',
- 'pragma': 'no-cache',
- 'referer': 'https://chat.vercel.ai/',
- 'sec-ch-ua': '"Chromium";v="122", "Not(A:Brand";v="24", "Google Chrome";v="122"',
- 'sec-ch-ua-mobile': '?0',
- 'sec-ch-ua-platform': '"macOS"',
- 'sec-fetch-dest': 'empty',
- 'sec-fetch-mode': 'cors',
- 'sec-fetch-site': 'same-origin',
- 'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36',
- }
-
- json_data = {
- 'messages': messages,
- 'id' : f'{os.urandom(3).hex()}a',
- }
- response = None
- for _ in range(max_retries):
- response = requests.post('https://chat.vercel.ai/api/chat',
- headers=headers, json=json_data, stream=True, proxies={"https": proxy})
- if not response.ok:
- continue
- for token in response.iter_content(chunk_size=None):
- try:
- yield token.decode(errors="ignore")
- except UnicodeDecodeError:
- pass
- break
- raise_for_status(response)
-
-def get_anti_bot_token() -> str:
- headers = {
- 'authority': 'sdk.vercel.ai',
- 'accept': '*/*',
- 'accept-language': 'en,fr-FR;q=0.9,fr;q=0.8,es-ES;q=0.7,es;q=0.6,en-US;q=0.5,am;q=0.4,de;q=0.3',
- 'cache-control': 'no-cache',
- 'pragma': 'no-cache',
- 'referer': 'https://sdk.vercel.ai/',
- 'sec-ch-ua': '"Google Chrome";v="117", "Not;A=Brand";v="8", "Chromium";v="117"',
- 'sec-ch-ua-mobile': '?0',
- 'sec-ch-ua-platform': '"macOS"',
- 'sec-fetch-dest': 'empty',
- 'sec-fetch-mode': 'cors',
- 'sec-fetch-site': 'same-origin',
- 'user-agent': f'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.{random.randint(99, 999)}.{random.randint(99, 999)} Safari/537.36',
- }
-
- response = requests.get('https://chat.vercel.ai/openai.jpeg',
- headers=headers).text
-
- raw_data = json.loads(base64.b64decode(response,
- validate=True))
-
- js_script = '''const globalThis={marker:"mark"};String.prototype.fontcolor=function(){return `<font>${this}</font>`};
- return (%s)(%s)''' % (raw_data['c'], raw_data['a'])
-
- sec_list = [execjs.compile(js_script).call('')[0], [], "sentinel"]
-
- raw_token = json.dumps({'r': sec_list, 't': raw_data['t']},
- separators = (",", ":"))
-
- return base64.b64encode(raw_token.encode('utf-8')).decode() \ No newline at end of file
diff --git a/g4f/Provider/You.py b/g4f/Provider/You.py
index af8aab0e..02735038 100644
--- a/g4f/Provider/You.py
+++ b/g4f/Provider/You.py
@@ -17,8 +17,6 @@ class You(AsyncGeneratorProvider, ProviderModelMixin):
label = "You.com"
url = "https://you.com"
working = True
- supports_gpt_35_turbo = True
- supports_gpt_4 = True
default_model = "gpt-4o-mini"
default_vision_model = "agent"
image_models = ["dall-e"]
diff --git a/g4f/Provider/__init__.py b/g4f/Provider/__init__.py
index e4c85d6a..1caf8aaf 100644
--- a/g4f/Provider/__init__.py
+++ b/g4f/Provider/__init__.py
@@ -5,60 +5,69 @@ from ..providers.retry_provider import RetryProvider, IterListProvider
from ..providers.base_provider import AsyncProvider, AsyncGeneratorProvider
from ..providers.create_images import CreateImagesProvider
-from .deprecated import *
-from .selenium import *
-from .needs_auth import *
+from .deprecated import *
+from .selenium import *
+from .needs_auth import *
+from .gigachat import *
+from .nexra import *
+
+from .Ai4Chat import Ai4Chat
from .AI365VIP import AI365VIP
+from .AIChatFree import AIChatFree
+from .AIUncensored import AIUncensored
from .Allyfy import Allyfy
+from .AmigoChat import AmigoChat
from .AiChatOnline import AiChatOnline
from .AiChats import AiChats
+from .AiMathGPT import AiMathGPT
from .Airforce import Airforce
from .Aura import Aura
from .Bing import Bing
from .BingCreateImages import BingCreateImages
-from .Binjie import Binjie
-from .Bixin123 import Bixin123
from .Blackbox import Blackbox
from .ChatGot import ChatGot
+from .ChatGpt import ChatGpt
from .Chatgpt4Online import Chatgpt4Online
from .Chatgpt4o import Chatgpt4o
+from .ChatGptEs import ChatGptEs
from .ChatgptFree import ChatgptFree
-from .CodeNews import CodeNews
+from .ChatHub import ChatHub
+from .ChatifyAI import ChatifyAI
+from .Cloudflare import Cloudflare
+from .DarkAI import DarkAI
from .DDG import DDG
from .DeepInfra import DeepInfra
+from .DeepInfraChat import DeepInfraChat
from .DeepInfraImage import DeepInfraImage
+from .Editee import Editee
from .FlowGpt import FlowGpt
from .Free2GPT import Free2GPT
from .FreeChatgpt import FreeChatgpt
from .FreeGpt import FreeGpt
from .FreeNetfly import FreeNetfly
from .GeminiPro import GeminiPro
-from .GigaChat import GigaChat
-from .GptTalkRu import GptTalkRu
+from .GizAI import GizAI
+from .GPROChat import GPROChat
from .HuggingChat import HuggingChat
from .HuggingFace import HuggingFace
from .Koala import Koala
from .Liaobots import Liaobots
-from .LiteIcoding import LiteIcoding
from .Local import Local
from .MagickPen import MagickPen
from .MetaAI import MetaAI
-from .MetaAIAccount import MetaAIAccount
-from .Nexra import Nexra
+#from .MetaAIAccount import MetaAIAccount
from .Ollama import Ollama
from .PerplexityLabs import PerplexityLabs
from .Pi import Pi
from .Pizzagpt import Pizzagpt
from .Prodia import Prodia
from .Reka import Reka
-from .Snova import Snova
from .Replicate import Replicate
from .ReplicateHome import ReplicateHome
+from .RubiksAI import RubiksAI
from .TeachAnything import TeachAnything
-from .TwitterBio import TwitterBio
from .Upstage import Upstage
-from .Vercel import Vercel
from .WhiteRabbitNeo import WhiteRabbitNeo
from .You import You
diff --git a/g4f/Provider/GigaChat.py b/g4f/Provider/gigachat/GigaChat.py
index 8ba07b43..b1b293e3 100644
--- a/g4f/Provider/GigaChat.py
+++ b/g4f/Provider/gigachat/GigaChat.py
@@ -9,10 +9,10 @@ import json
from aiohttp import ClientSession, TCPConnector, BaseConnector
from g4f.requests import raise_for_status
-from ..typing import AsyncResult, Messages
-from .base_provider import AsyncGeneratorProvider, ProviderModelMixin
-from ..errors import MissingAuthError
-from .helper import get_connector
+from ...typing import AsyncResult, Messages
+from ..base_provider import AsyncGeneratorProvider, ProviderModelMixin
+from ...errors import MissingAuthError
+from ..helper import get_connector
access_token = ""
token_expires_at = 0
@@ -45,7 +45,7 @@ class GigaChat(AsyncGeneratorProvider, ProviderModelMixin):
if not api_key:
raise MissingAuthError('Missing "api_key"')
- cafile = os.path.join(os.path.dirname(__file__), "gigachat_crt/russian_trusted_root_ca_pem.crt")
+ cafile = os.path.join(os.path.dirname(__file__), "russian_trusted_root_ca_pem.crt")
ssl_context = ssl.create_default_context(cafile=cafile) if os.path.exists(cafile) else None
if connector is None and ssl_context is not None:
connector = TCPConnector(ssl_context=ssl_context)
diff --git a/g4f/Provider/gigachat/__init__.py b/g4f/Provider/gigachat/__init__.py
new file mode 100644
index 00000000..c9853742
--- /dev/null
+++ b/g4f/Provider/gigachat/__init__.py
@@ -0,0 +1,2 @@
+from .GigaChat import GigaChat
+
diff --git a/g4f/Provider/gigachat_crt/russian_trusted_root_ca_pem.crt b/g4f/Provider/gigachat/russian_trusted_root_ca_pem.crt
index 4c143a21..4c143a21 100644
--- a/g4f/Provider/gigachat_crt/russian_trusted_root_ca_pem.crt
+++ b/g4f/Provider/gigachat/russian_trusted_root_ca_pem.crt
diff --git a/g4f/Provider/needs_auth/Gemini.py b/g4f/Provider/needs_auth/Gemini.py
index eddd25fa..8d741476 100644
--- a/g4f/Provider/needs_auth/Gemini.py
+++ b/g4f/Provider/needs_auth/Gemini.py
@@ -54,6 +54,7 @@ class Gemini(AsyncGeneratorProvider):
url = "https://gemini.google.com"
needs_auth = True
working = True
+ default_model = 'gemini'
image_models = ["gemini"]
default_vision_model = "gemini"
_cookies: Cookies = None
@@ -305,4 +306,4 @@ class Conversation(BaseConversation):
) -> None:
self.conversation_id = conversation_id
self.response_id = response_id
- self.choice_id = choice_id \ No newline at end of file
+ self.choice_id = choice_id
diff --git a/g4f/Provider/needs_auth/Groq.py b/g4f/Provider/needs_auth/Groq.py
index d11f6a82..027d98bf 100644
--- a/g4f/Provider/needs_auth/Groq.py
+++ b/g4f/Provider/needs_auth/Groq.py
@@ -8,7 +8,26 @@ class Groq(Openai):
url = "https://console.groq.com/playground"
working = True
default_model = "mixtral-8x7b-32768"
- models = ["mixtral-8x7b-32768", "llama2-70b-4096", "gemma-7b-it"]
+ models = [
+ "distil-whisper-large-v3-en",
+ "gemma2-9b-it",
+ "gemma-7b-it",
+ "llama3-groq-70b-8192-tool-use-preview",
+ "llama3-groq-8b-8192-tool-use-preview",
+ "llama-3.1-70b-versatile",
+ "llama-3.1-8b-instant",
+ "llama-3.2-1b-preview",
+ "llama-3.2-3b-preview",
+ "llama-3.2-11b-vision-preview",
+ "llama-3.2-90b-vision-preview",
+ "llama-guard-3-8b",
+ "llava-v1.5-7b-4096-preview",
+ "llama3-70b-8192",
+ "llama3-8b-8192",
+ "mixtral-8x7b-32768",
+ "whisper-large-v3",
+ "whisper-large-v3-turbo",
+ ]
model_aliases = {"mixtral-8x7b": "mixtral-8x7b-32768", "llama2-70b": "llama2-70b-4096"}
@classmethod
@@ -21,4 +40,4 @@ class Groq(Openai):
) -> AsyncResult:
return super().create_async_generator(
model, messages, api_base=api_base, **kwargs
- ) \ No newline at end of file
+ )
diff --git a/g4f/Provider/needs_auth/OpenRouter.py b/g4f/Provider/needs_auth/OpenRouter.py
index 7945784a..5e0bf336 100644
--- a/g4f/Provider/needs_auth/OpenRouter.py
+++ b/g4f/Provider/needs_auth/OpenRouter.py
@@ -8,7 +8,7 @@ from ...typing import AsyncResult, Messages
class OpenRouter(Openai):
label = "OpenRouter"
url = "https://openrouter.ai"
- working = True
+ working = False
default_model = "mistralai/mistral-7b-instruct:free"
@classmethod
@@ -29,4 +29,4 @@ class OpenRouter(Openai):
) -> AsyncResult:
return super().create_async_generator(
model, messages, api_base=api_base, **kwargs
- ) \ No newline at end of file
+ )
diff --git a/g4f/Provider/needs_auth/Openai.py b/g4f/Provider/needs_auth/Openai.py
index a0740c47..382ebada 100644
--- a/g4f/Provider/needs_auth/Openai.py
+++ b/g4f/Provider/needs_auth/Openai.py
@@ -11,7 +11,7 @@ from ...image import to_data_uri
class Openai(AsyncGeneratorProvider, ProviderModelMixin):
label = "OpenAI API"
- url = "https://openai.com"
+ url = "https://platform.openai.com"
working = True
needs_auth = True
supports_message_history = True
diff --git a/g4f/Provider/needs_auth/OpenaiChat.py b/g4f/Provider/needs_auth/OpenaiChat.py
index 82462040..f02121e3 100644
--- a/g4f/Provider/needs_auth/OpenaiChat.py
+++ b/g4f/Provider/needs_auth/OpenaiChat.py
@@ -61,9 +61,11 @@ class OpenaiChat(AsyncGeneratorProvider, ProviderModelMixin):
default_model = None
default_vision_model = "gpt-4o"
models = [ "auto", "gpt-4o-mini", "gpt-4o", "gpt-4", "gpt-4-gizmo"]
+
model_aliases = {
- "gpt-4-turbo-preview": "gpt-4",
- "dall-e": "gpt-4",
+ #"gpt-4-turbo": "gpt-4",
+ #"gpt-4": "gpt-4-gizmo",
+ #"dalle": "gpt-4",
}
_api_key: str = None
_headers: dict = None
diff --git a/g4f/Provider/needs_auth/PerplexityApi.py b/g4f/Provider/needs_auth/PerplexityApi.py
index 35d8d9d6..3ee65b30 100644
--- a/g4f/Provider/needs_auth/PerplexityApi.py
+++ b/g4f/Provider/needs_auth/PerplexityApi.py
@@ -15,7 +15,6 @@ class PerplexityApi(Openai):
"llama-3-sonar-large-32k-online",
"llama-3-8b-instruct",
"llama-3-70b-instruct",
- "mixtral-8x7b-instruct"
]
@classmethod
@@ -28,4 +27,4 @@ class PerplexityApi(Openai):
) -> AsyncResult:
return super().create_async_generator(
model, messages, api_base=api_base, **kwargs
- ) \ No newline at end of file
+ )
diff --git a/g4f/Provider/needs_auth/__init__.py b/g4f/Provider/needs_auth/__init__.py
index b5463b71..0492645d 100644
--- a/g4f/Provider/needs_auth/__init__.py
+++ b/g4f/Provider/needs_auth/__init__.py
@@ -7,5 +7,5 @@ from .Poe import Poe
from .Openai import Openai
from .Groq import Groq
from .OpenRouter import OpenRouter
-from .OpenaiAccount import OpenaiAccount
-from .PerplexityApi import PerplexityApi \ No newline at end of file
+#from .OpenaiAccount import OpenaiAccount
+from .PerplexityApi import PerplexityApi
diff --git a/g4f/Provider/nexra/NexraBing.py b/g4f/Provider/nexra/NexraBing.py
new file mode 100644
index 00000000..28f0b117
--- /dev/null
+++ b/g4f/Provider/nexra/NexraBing.py
@@ -0,0 +1,93 @@
+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 NexraBing(AbstractProvider, ProviderModelMixin):
+ label = "Nexra Bing"
+ url = "https://nexra.aryahcr.cc/documentation/bing/en"
+ api_endpoint = "https://nexra.aryahcr.cc/api/chat/complements"
+ working = True
+ supports_stream = True
+
+ default_model = 'Balanced'
+ models = [default_model, 'Creative', 'Precise']
+
+ model_aliases = {
+ "gpt-4": "Balanced",
+ "gpt-4": "Creative",
+ "gpt-4": "Precise",
+ }
+
+ @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 = False,
+ 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)
+ }
+ ],
+ "conversation_style": model,
+ "markdown": markdown,
+ "stream": stream,
+ "model": "Bing"
+ }
+
+ response = requests.post(cls.api_endpoint, headers=headers, json=data, stream=True)
+
+ return cls.process_response(response)
+
+ @classmethod
+ def process_response(cls, response):
+ if response.status_code != 200:
+ yield f"Error: {response.status_code}"
+ return
+
+ full_message = ""
+ for chunk in response.iter_content(chunk_size=None):
+ if chunk:
+ messages = chunk.decode('utf-8').split('\x1e')
+ for message in messages:
+ try:
+ json_data = json.loads(message)
+ if json_data.get('finish', False):
+ return
+ current_message = json_data.get('message', '')
+ if current_message:
+ new_content = current_message[len(full_message):]
+ if new_content:
+ yield new_content
+ full_message = current_message
+ except json.JSONDecodeError:
+ continue
+
+ if not full_message:
+ yield "No message received"
diff --git a/g4f/Provider/nexra/NexraBlackbox.py b/g4f/Provider/nexra/NexraBlackbox.py
new file mode 100644
index 00000000..be048fdd
--- /dev/null
+++ b/g4f/Provider/nexra/NexraBlackbox.py
@@ -0,0 +1,100 @@
+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 NexraBlackbox(AbstractProvider, ProviderModelMixin):
+ label = "Nexra Blackbox"
+ url = "https://nexra.aryahcr.cc/documentation/blackbox/en"
+ api_endpoint = "https://nexra.aryahcr.cc/api/chat/complements"
+ working = True
+ supports_stream = True
+
+ default_model = "blackbox"
+ models = [default_model]
+ model_aliases = {"blackboxai": "blackbox",}
+
+ @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,
+ websearch: bool = False,
+ **kwargs
+ ) -> CreateResult:
+ model = cls.get_model(model)
+
+ headers = {
+ 'Content-Type': 'application/json'
+ }
+
+ data = {
+ "messages": [
+ {
+ "role": "user",
+ "content": format_prompt(messages)
+ }
+ ],
+ "websearch": websearch,
+ "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:
+ full_response = ""
+ for line in response.iter_lines(decode_unicode=True):
+ if line:
+ data = json.loads(line)
+ if data.get('finish'):
+ break
+ message = data.get('message', '')
+ if message:
+ full_response = message
+ return full_response
+ except json.JSONDecodeError:
+ return "Error: Unable to decode JSON response"
+ else:
+ return f"Error: {response.status_code}"
+
+ @classmethod
+ def process_streaming_response(cls, response):
+ previous_message = ""
+ for line in response.iter_lines(decode_unicode=True):
+ if line:
+ try:
+ data = json.loads(line)
+ if data.get('finish'):
+ break
+ message = data.get('message', '')
+ if message and message != previous_message:
+ yield message[len(previous_message):]
+ previous_message = message
+ except json.JSONDecodeError:
+ pass
diff --git a/g4f/Provider/nexra/NexraChatGPT.py b/g4f/Provider/nexra/NexraChatGPT.py
new file mode 100644
index 00000000..074a0363
--- /dev/null
+++ b/g4f/Provider/nexra/NexraChatGPT.py
@@ -0,0 +1,285 @@
+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", "")
diff --git a/g4f/Provider/nexra/NexraDallE.py b/g4f/Provider/nexra/NexraDallE.py
new file mode 100644
index 00000000..f605c6d0
--- /dev/null
+++ b/g4f/Provider/nexra/NexraDallE.py
@@ -0,0 +1,63 @@
+from __future__ import annotations
+
+import json
+import requests
+from ...typing import CreateResult, Messages
+from ..base_provider import ProviderModelMixin, AbstractProvider
+from ...image import ImageResponse
+
+class NexraDallE(AbstractProvider, ProviderModelMixin):
+ label = "Nexra DALL-E"
+ url = "https://nexra.aryahcr.cc/documentation/dall-e/en"
+ api_endpoint = "https://nexra.aryahcr.cc/api/image/complements"
+ working = True
+
+ default_model = "dalle"
+ models = [default_model]
+
+ @classmethod
+ def get_model(cls, model: str) -> str:
+ return cls.default_model
+
+ @classmethod
+ def create_completion(
+ cls,
+ model: str,
+ messages: Messages,
+ proxy: str = None,
+ response: str = "url", # base64 or url
+ **kwargs
+ ) -> CreateResult:
+ model = cls.get_model(model)
+
+ headers = {
+ 'Content-Type': 'application/json'
+ }
+
+ data = {
+ "prompt": messages[-1]["content"],
+ "model": model,
+ "response": response
+ }
+
+ response = requests.post(cls.api_endpoint, headers=headers, json=data)
+
+ result = cls.process_response(response)
+ yield result
+
+ @classmethod
+ def process_response(cls, response):
+ if response.status_code == 200:
+ try:
+ content = response.text.strip()
+ content = content.lstrip('_')
+ data = json.loads(content)
+ if data.get('status') and data.get('images'):
+ image_url = data['images'][0]
+ return ImageResponse(images=[image_url], alt="Generated Image")
+ else:
+ return "Error: No image URL found in the response"
+ except json.JSONDecodeError as e:
+ return f"Error: Unable to decode JSON response. Details: {str(e)}"
+ else:
+ return f"Error: {response.status_code}, Response: {response.text}"
diff --git a/g4f/Provider/nexra/NexraDallE2.py b/g4f/Provider/nexra/NexraDallE2.py
new file mode 100644
index 00000000..2a36b6e6
--- /dev/null
+++ b/g4f/Provider/nexra/NexraDallE2.py
@@ -0,0 +1,63 @@
+from __future__ import annotations
+
+import json
+import requests
+from ...typing import CreateResult, Messages
+from ..base_provider import ProviderModelMixin, AbstractProvider
+from ...image import ImageResponse
+
+class NexraDallE2(AbstractProvider, ProviderModelMixin):
+ label = "Nexra DALL-E 2"
+ url = "https://nexra.aryahcr.cc/documentation/dall-e/en"
+ api_endpoint = "https://nexra.aryahcr.cc/api/image/complements"
+ working = True
+
+ default_model = "dalle2"
+ models = [default_model]
+
+ @classmethod
+ def get_model(cls, model: str) -> str:
+ return cls.default_model
+
+ @classmethod
+ def create_completion(
+ cls,
+ model: str,
+ messages: Messages,
+ proxy: str = None,
+ response: str = "url", # base64 or url
+ **kwargs
+ ) -> CreateResult:
+ model = cls.get_model(model)
+
+ headers = {
+ 'Content-Type': 'application/json'
+ }
+
+ data = {
+ "prompt": messages[-1]["content"],
+ "model": model,
+ "response": response
+ }
+
+ response = requests.post(cls.api_endpoint, headers=headers, json=data)
+
+ result = cls.process_response(response)
+ yield result
+
+ @classmethod
+ def process_response(cls, response):
+ if response.status_code == 200:
+ try:
+ content = response.text.strip()
+ content = content.lstrip('_')
+ data = json.loads(content)
+ if data.get('status') and data.get('images'):
+ image_url = data['images'][0]
+ return ImageResponse(images=[image_url], alt="Generated Image")
+ else:
+ return "Error: No image URL found in the response"
+ except json.JSONDecodeError as e:
+ return f"Error: Unable to decode JSON response. Details: {str(e)}"
+ else:
+ return f"Error: {response.status_code}, Response: {response.text}"
diff --git a/g4f/Provider/nexra/NexraEmi.py b/g4f/Provider/nexra/NexraEmi.py
new file mode 100644
index 00000000..c26becec
--- /dev/null
+++ b/g4f/Provider/nexra/NexraEmi.py
@@ -0,0 +1,63 @@
+from __future__ import annotations
+
+import json
+import requests
+from ...typing import CreateResult, Messages
+from ..base_provider import ProviderModelMixin, AbstractProvider
+from ...image import ImageResponse
+
+class NexraEmi(AbstractProvider, ProviderModelMixin):
+ label = "Nexra Emi"
+ url = "https://nexra.aryahcr.cc/documentation/emi/en"
+ api_endpoint = "https://nexra.aryahcr.cc/api/image/complements"
+ working = True
+
+ default_model = "emi"
+ models = [default_model]
+
+ @classmethod
+ def get_model(cls, model: str) -> str:
+ return cls.default_model
+
+ @classmethod
+ def create_completion(
+ cls,
+ model: str,
+ messages: Messages,
+ proxy: str = None,
+ response: str = "url", # base64 or url
+ **kwargs
+ ) -> CreateResult:
+ model = cls.get_model(model)
+
+ headers = {
+ 'Content-Type': 'application/json'
+ }
+
+ data = {
+ "prompt": messages[-1]["content"],
+ "model": model,
+ "response": response
+ }
+
+ response = requests.post(cls.api_endpoint, headers=headers, json=data)
+
+ result = cls.process_response(response)
+ yield result
+
+ @classmethod
+ def process_response(cls, response):
+ if response.status_code == 200:
+ try:
+ content = response.text.strip()
+ content = content.lstrip('_')
+ data = json.loads(content)
+ if data.get('status') and data.get('images'):
+ image_url = data['images'][0]
+ return ImageResponse(images=[image_url], alt="Generated Image")
+ else:
+ return "Error: No image URL found in the response"
+ except json.JSONDecodeError as e:
+ return f"Error: Unable to decode JSON response. Details: {str(e)}"
+ else:
+ return f"Error: {response.status_code}, Response: {response.text}"
diff --git a/g4f/Provider/nexra/NexraFluxPro.py b/g4f/Provider/nexra/NexraFluxPro.py
new file mode 100644
index 00000000..cfb26385
--- /dev/null
+++ b/g4f/Provider/nexra/NexraFluxPro.py
@@ -0,0 +1,70 @@
+from __future__ import annotations
+
+import json
+import requests
+from ...typing import CreateResult, Messages
+from ..base_provider import ProviderModelMixin, AbstractProvider
+from ...image import ImageResponse
+
+class NexraFluxPro(AbstractProvider, ProviderModelMixin):
+ url = "https://nexra.aryahcr.cc/documentation/flux-pro/en"
+ api_endpoint = "https://nexra.aryahcr.cc/api/image/complements"
+ working = True
+
+ default_model = 'flux'
+ models = [default_model]
+ model_aliases = {
+ "flux-pro": "flux",
+ }
+
+ @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,
+ response: str = "url", # base64 or url
+ **kwargs
+ ) -> CreateResult:
+ model = cls.get_model(model)
+
+ headers = {
+ 'Content-Type': 'application/json'
+ }
+
+ data = {
+ "prompt": messages[-1]["content"],
+ "model": model,
+ "response": response
+ }
+
+ response = requests.post(cls.api_endpoint, headers=headers, json=data)
+
+ result = cls.process_response(response)
+ yield result
+
+ @classmethod
+ def process_response(cls, response):
+ if response.status_code == 200:
+ try:
+ content = response.text.strip()
+ content = content.lstrip('_')
+ data = json.loads(content)
+ if data.get('status') and data.get('images'):
+ image_url = data['images'][0]
+ return ImageResponse(images=[image_url], alt="Generated Image")
+ else:
+ return "Error: No image URL found in the response"
+ except json.JSONDecodeError as e:
+ return f"Error: Unable to decode JSON response. Details: {str(e)}"
+ else:
+ return f"Error: {response.status_code}, Response: {response.text}"
diff --git a/g4f/Provider/nexra/NexraGeminiPro.py b/g4f/Provider/nexra/NexraGeminiPro.py
new file mode 100644
index 00000000..e4e6a8ec
--- /dev/null
+++ b/g4f/Provider/nexra/NexraGeminiPro.py
@@ -0,0 +1,86 @@
+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 NexraGeminiPro(AbstractProvider, ProviderModelMixin):
+ label = "Nexra Gemini PRO"
+ url = "https://nexra.aryahcr.cc/documentation/gemini-pro/en"
+ api_endpoint = "https://nexra.aryahcr.cc/api/chat/complements"
+ working = True
+ supports_stream = True
+
+ default_model = 'gemini-pro'
+ 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:
+ yield message[len(full_message):]
+ full_message = message
+ except json.JSONDecodeError:
+ pass
diff --git a/g4f/Provider/nexra/NexraMidjourney.py b/g4f/Provider/nexra/NexraMidjourney.py
new file mode 100644
index 00000000..c427f8a0
--- /dev/null
+++ b/g4f/Provider/nexra/NexraMidjourney.py
@@ -0,0 +1,63 @@
+from __future__ import annotations
+
+import json
+import requests
+from ...typing import CreateResult, Messages
+from ..base_provider import ProviderModelMixin, AbstractProvider
+from ...image import ImageResponse
+
+class NexraMidjourney(AbstractProvider, ProviderModelMixin):
+ label = "Nexra Midjourney"
+ url = "https://nexra.aryahcr.cc/documentation/midjourney/en"
+ api_endpoint = "https://nexra.aryahcr.cc/api/image/complements"
+ working = True
+
+ default_model = "midjourney"
+ models = [default_model]
+
+ @classmethod
+ def get_model(cls, model: str) -> str:
+ return cls.default_model
+
+ @classmethod
+ def create_completion(
+ cls,
+ model: str,
+ messages: Messages,
+ proxy: str = None,
+ response: str = "url", # base64 or url
+ **kwargs
+ ) -> CreateResult:
+ model = cls.get_model(model)
+
+ headers = {
+ 'Content-Type': 'application/json'
+ }
+
+ data = {
+ "prompt": messages[-1]["content"],
+ "model": model,
+ "response": response
+ }
+
+ response = requests.post(cls.api_endpoint, headers=headers, json=data)
+
+ result = cls.process_response(response)
+ yield result
+
+ @classmethod
+ def process_response(cls, response):
+ if response.status_code == 200:
+ try:
+ content = response.text.strip()
+ content = content.lstrip('_')
+ data = json.loads(content)
+ if data.get('status') and data.get('images'):
+ image_url = data['images'][0]
+ return ImageResponse(images=[image_url], alt="Generated Image")
+ else:
+ return "Error: No image URL found in the response"
+ except json.JSONDecodeError as e:
+ return f"Error: Unable to decode JSON response. Details: {str(e)}"
+ else:
+ return f"Error: {response.status_code}, Response: {response.text}"
diff --git a/g4f/Provider/nexra/NexraProdiaAI.py b/g4f/Provider/nexra/NexraProdiaAI.py
new file mode 100644
index 00000000..de997fce
--- /dev/null
+++ b/g4f/Provider/nexra/NexraProdiaAI.py
@@ -0,0 +1,151 @@
+from __future__ import annotations
+
+import json
+import requests
+from ...typing import CreateResult, Messages
+from ..base_provider import ProviderModelMixin, AbstractProvider
+from ...image import ImageResponse
+
+class NexraProdiaAI(AbstractProvider, ProviderModelMixin):
+ label = "Nexra Prodia AI"
+ url = "https://nexra.aryahcr.cc/documentation/prodia/en"
+ api_endpoint = "https://nexra.aryahcr.cc/api/image/complements"
+ working = True
+
+ default_model = 'absolutereality_v181.safetensors [3d9d4d2b]'
+ models = [
+ '3Guofeng3_v34.safetensors [50f420de]',
+ 'absolutereality_V16.safetensors [37db0fc3]',
+ default_model,
+ 'amIReal_V41.safetensors [0a8a2e61]',
+ 'analog-diffusion-1.0.ckpt [9ca13f02]',
+ 'aniverse_v30.safetensors [579e6f85]',
+ 'anythingv3_0-pruned.ckpt [2700c435]',
+ 'anything-v4.5-pruned.ckpt [65745d25]',
+ 'anythingV5_PrtRE.safetensors [893e49b9]',
+ 'AOM3A3_orangemixs.safetensors [9600da17]',
+ 'blazing_drive_v10g.safetensors [ca1c1eab]',
+ 'breakdomain_I2428.safetensors [43cc7d2f]',
+ 'breakdomain_M2150.safetensors [15f7afca]',
+ 'cetusMix_Version35.safetensors [de2f2560]',
+ 'childrensStories_v13D.safetensors [9dfaabcb]',
+ 'childrensStories_v1SemiReal.safetensors [a1c56dbb]',
+ 'childrensStories_v1ToonAnime.safetensors [2ec7b88b]',
+ 'Counterfeit_v30.safetensors [9e2a8f19]',
+ 'cuteyukimixAdorable_midchapter3.safetensors [04bdffe6]',
+ 'cyberrealistic_v33.safetensors [82b0d085]',
+ 'dalcefo_v4.safetensors [425952fe]',
+ 'deliberate_v2.safetensors [10ec4b29]',
+ 'deliberate_v3.safetensors [afd9d2d4]',
+ 'dreamlike-anime-1.0.safetensors [4520e090]',
+ 'dreamlike-diffusion-1.0.safetensors [5c9fd6e0]',
+ 'dreamlike-photoreal-2.0.safetensors [fdcf65e7]',
+ 'dreamshaper_6BakedVae.safetensors [114c8abb]',
+ 'dreamshaper_7.safetensors [5cf5ae06]',
+ 'dreamshaper_8.safetensors [9d40847d]',
+ 'edgeOfRealism_eorV20.safetensors [3ed5de15]',
+ 'EimisAnimeDiffusion_V1.ckpt [4f828a15]',
+ 'elldreths-vivid-mix.safetensors [342d9d26]',
+ 'epicphotogasm_xPlusPlus.safetensors [1a8f6d35]',
+ 'epicrealism_naturalSinRC1VAE.safetensors [90a4c676]',
+ 'epicrealism_pureEvolutionV3.safetensors [42c8440c]',
+ 'ICantBelieveItsNotPhotography_seco.safetensors [4e7a3dfd]',
+ 'indigoFurryMix_v75Hybrid.safetensors [91208cbb]',
+ 'juggernaut_aftermath.safetensors [5e20c455]',
+ 'lofi_v4.safetensors [ccc204d6]',
+ 'lyriel_v16.safetensors [68fceea2]',
+ 'majicmixRealistic_v4.safetensors [29d0de58]',
+ 'mechamix_v10.safetensors [ee685731]',
+ 'meinamix_meinaV9.safetensors [2ec66ab0]',
+ 'meinamix_meinaV11.safetensors [b56ce717]',
+ 'neverendingDream_v122.safetensors [f964ceeb]',
+ 'openjourney_V4.ckpt [ca2f377f]',
+ 'pastelMixStylizedAnime_pruned_fp16.safetensors [793a26e8]',
+ 'portraitplus_V1.0.safetensors [1400e684]',
+ 'protogenx34.safetensors [5896f8d5]',
+ 'Realistic_Vision_V1.4-pruned-fp16.safetensors [8d21810b]',
+ 'Realistic_Vision_V2.0.safetensors [79587710]',
+ 'Realistic_Vision_V4.0.safetensors [29a7afaa]',
+ 'Realistic_Vision_V5.0.safetensors [614d1063]',
+ 'Realistic_Vision_V5.1.safetensors [a0f13c83]',
+ 'redshift_diffusion-V10.safetensors [1400e684]',
+ 'revAnimated_v122.safetensors [3f4fefd9]',
+ 'rundiffusionFX25D_v10.safetensors [cd12b0ee]',
+ 'rundiffusionFX_v10.safetensors [cd4e694d]',
+ 'sdv1_4.ckpt [7460a6fa]',
+ 'v1-5-pruned-emaonly.safetensors [d7049739]',
+ 'v1-5-inpainting.safetensors [21c7ab71]',
+ 'shoninsBeautiful_v10.safetensors [25d8c546]',
+ 'theallys-mix-ii-churned.safetensors [5d9225a4]',
+ 'timeless-1.0.ckpt [7c4971d4]',
+ 'toonyou_beta6.safetensors [980f6b15]',
+ ]
+
+ model_aliases = {}
+
+ @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 get_model(cls, model: str) -> str:
+ return cls.default_model
+
+ @classmethod
+ def create_completion(
+ cls,
+ model: str,
+ messages: Messages,
+ proxy: str = None,
+ response: str = "url", # base64 or url
+ steps: str = 25, # Min: 1, Max: 30
+ cfg_scale: str = 7, # Min: 0, Max: 20
+ sampler: str = "DPM++ 2M Karras", # Select from these: "Euler","Euler a","Heun","DPM++ 2M Karras","DPM++ SDE Karras","DDIM"
+ negative_prompt: str = "", # Indicates what the AI should not do
+ **kwargs
+ ) -> CreateResult:
+ model = cls.get_model(model)
+
+ headers = {
+ 'Content-Type': 'application/json'
+ }
+
+ data = {
+ "prompt": messages[-1]["content"],
+ "model": "prodia",
+ "response": response,
+ "data": {
+ "model": model,
+ "steps": steps,
+ "cfg_scale": cfg_scale,
+ "sampler": sampler,
+ "negative_prompt": negative_prompt
+ }
+ }
+
+ response = requests.post(cls.api_endpoint, headers=headers, json=data)
+
+ result = cls.process_response(response)
+ yield result
+
+ @classmethod
+ def process_response(cls, response):
+ if response.status_code == 200:
+ try:
+ content = response.text.strip()
+ content = content.lstrip('_') # Remove leading underscores
+ data = json.loads(content)
+ if data.get('status') and data.get('images'):
+ image_url = data['images'][0]
+ return ImageResponse(images=[image_url], alt="Generated Image")
+ else:
+ return "Error: No image URL found in the response"
+ except json.JSONDecodeError as e:
+ return f"Error: Unable to decode JSON response. Details: {str(e)}"
+ else:
+ return f"Error: {response.status_code}, Response: {response.text}"
diff --git a/g4f/Provider/nexra/NexraQwen.py b/g4f/Provider/nexra/NexraQwen.py
new file mode 100644
index 00000000..7f944e44
--- /dev/null
+++ b/g4f/Provider/nexra/NexraQwen.py
@@ -0,0 +1,86 @@
+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 NexraQwen(AbstractProvider, ProviderModelMixin):
+ label = "Nexra Qwen"
+ url = "https://nexra.aryahcr.cc/documentation/qwen/en"
+ api_endpoint = "https://nexra.aryahcr.cc/api/chat/complements"
+ working = True
+ supports_stream = True
+
+ default_model = 'qwen'
+ 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 is not None and message != full_message:
+ yield message[len(full_message):]
+ full_message = message
+ except json.JSONDecodeError:
+ pass
diff --git a/g4f/Provider/nexra/NexraSD15.py b/g4f/Provider/nexra/NexraSD15.py
new file mode 100644
index 00000000..860a132f
--- /dev/null
+++ b/g4f/Provider/nexra/NexraSD15.py
@@ -0,0 +1,72 @@
+from __future__ import annotations
+
+import json
+import requests
+from ...typing import CreateResult, Messages
+from ..base_provider import ProviderModelMixin, AbstractProvider
+from ...image import ImageResponse
+
+class NexraSD15(AbstractProvider, ProviderModelMixin):
+ label = "Nexra Stable Diffusion 1.5"
+ url = "https://nexra.aryahcr.cc/documentation/stable-diffusion/en"
+ api_endpoint = "https://nexra.aryahcr.cc/api/image/complements"
+ working = True
+
+ default_model = 'stablediffusion-1.5'
+ models = [default_model]
+
+ model_aliases = {
+ "sd-1.5": "stablediffusion-1.5",
+ }
+
+ @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,
+ response: str = "url", # base64 or url
+ **kwargs
+ ) -> CreateResult:
+ model = cls.get_model(model)
+
+ headers = {
+ 'Content-Type': 'application/json'
+ }
+
+ data = {
+ "prompt": messages[-1]["content"],
+ "model": model,
+ "response": response
+ }
+
+ response = requests.post(cls.api_endpoint, headers=headers, json=data)
+
+ result = cls.process_response(response)
+ yield result
+
+ @classmethod
+ def process_response(cls, response):
+ if response.status_code == 200:
+ try:
+ content = response.text.strip()
+ content = content.lstrip('_')
+ data = json.loads(content)
+ if data.get('status') and data.get('images'):
+ image_url = data['images'][0]
+ return ImageResponse(images=[image_url], alt="Generated Image")
+ else:
+ return "Error: No image URL found in the response"
+ except json.JSONDecodeError as e:
+ return f"Error: Unable to decode JSON response. Details: {str(e)}"
+ else:
+ return f"Error: {response.status_code}, Response: {response.text}"
diff --git a/g4f/Provider/nexra/NexraSDLora.py b/g4f/Provider/nexra/NexraSDLora.py
new file mode 100644
index 00000000..a12bff1a
--- /dev/null
+++ b/g4f/Provider/nexra/NexraSDLora.py
@@ -0,0 +1,69 @@
+from __future__ import annotations
+
+import json
+import requests
+from ...typing import CreateResult, Messages
+from ..base_provider import ProviderModelMixin, AbstractProvider
+from ...image import ImageResponse
+
+class NexraSDLora(AbstractProvider, ProviderModelMixin):
+ label = "Nexra Stable Diffusion Lora"
+ url = "https://nexra.aryahcr.cc/documentation/stable-diffusion/en"
+ api_endpoint = "https://nexra.aryahcr.cc/api/image/complements"
+ working = True
+
+ default_model = "sdxl-lora"
+ models = [default_model]
+
+ @classmethod
+ def get_model(cls, model: str) -> str:
+ return cls.default_model
+
+ @classmethod
+ def create_completion(
+ cls,
+ model: str,
+ messages: Messages,
+ proxy: str = None,
+ response: str = "url", # base64 or url
+ guidance: str = 0.3, # Min: 0, Max: 5
+ steps: str = 2, # Min: 2, Max: 10
+ **kwargs
+ ) -> CreateResult:
+ model = cls.get_model(model)
+
+ headers = {
+ 'Content-Type': 'application/json'
+ }
+
+ data = {
+ "prompt": messages[-1]["content"],
+ "model": model,
+ "response": response,
+ "data": {
+ "guidance": guidance,
+ "steps": steps
+ }
+ }
+
+ response = requests.post(cls.api_endpoint, headers=headers, json=data)
+
+ result = cls.process_response(response)
+ yield result
+
+ @classmethod
+ def process_response(cls, response):
+ if response.status_code == 200:
+ try:
+ content = response.text.strip()
+ content = content.lstrip('_')
+ data = json.loads(content)
+ if data.get('status') and data.get('images'):
+ image_url = data['images'][0]
+ return ImageResponse(images=[image_url], alt="Generated Image")
+ else:
+ return "Error: No image URL found in the response"
+ except json.JSONDecodeError as e:
+ return f"Error: Unable to decode JSON response. Details: {str(e)}"
+ else:
+ return f"Error: {response.status_code}, Response: {response.text}"
diff --git a/g4f/Provider/nexra/NexraSDTurbo.py b/g4f/Provider/nexra/NexraSDTurbo.py
new file mode 100644
index 00000000..865b4522
--- /dev/null
+++ b/g4f/Provider/nexra/NexraSDTurbo.py
@@ -0,0 +1,69 @@
+from __future__ import annotations
+
+import json
+import requests
+from ...typing import CreateResult, Messages
+from ..base_provider import ProviderModelMixin, AbstractProvider
+from ...image import ImageResponse
+
+class NexraSDTurbo(AbstractProvider, ProviderModelMixin):
+ label = "Nexra Stable Diffusion Turbo"
+ url = "https://nexra.aryahcr.cc/documentation/stable-diffusion/en"
+ api_endpoint = "https://nexra.aryahcr.cc/api/image/complements"
+ working = True
+
+ default_model = "sdxl-turbo"
+ models = [default_model]
+
+ @classmethod
+ def get_model(cls, model: str) -> str:
+ return cls.default_model
+
+ @classmethod
+ def create_completion(
+ cls,
+ model: str,
+ messages: Messages,
+ proxy: str = None,
+ response: str = "url", # base64 or url
+ strength: str = 0.7, # Min: 0, Max: 1
+ steps: str = 2, # Min: 1, Max: 10
+ **kwargs
+ ) -> CreateResult:
+ model = cls.get_model(model)
+
+ headers = {
+ 'Content-Type': 'application/json'
+ }
+
+ data = {
+ "prompt": messages[-1]["content"],
+ "model": model,
+ "response": response,
+ "data": {
+ "strength": strength,
+ "steps": steps
+ }
+ }
+
+ response = requests.post(cls.api_endpoint, headers=headers, json=data)
+
+ result = cls.process_response(response)
+ yield result
+
+ @classmethod
+ def process_response(cls, response):
+ if response.status_code == 200:
+ try:
+ content = response.text.strip()
+ content = content.lstrip('_') # Remove the leading underscore
+ data = json.loads(content)
+ if data.get('status') and data.get('images'):
+ image_url = data['images'][0]
+ return ImageResponse(images=[image_url], alt="Generated Image")
+ else:
+ return "Error: No image URL found in the response"
+ except json.JSONDecodeError as e:
+ return f"Error: Unable to decode JSON response. Details: {str(e)}"
+ else:
+ return f"Error: {response.status_code}, Response: {response.text}"
diff --git a/g4f/Provider/nexra/__init__.py b/g4f/Provider/nexra/__init__.py
new file mode 100644
index 00000000..bebc1fb6
--- /dev/null
+++ b/g4f/Provider/nexra/__init__.py
@@ -0,0 +1,14 @@
+from .NexraBing import NexraBing
+from .NexraBlackbox import NexraBlackbox
+from .NexraChatGPT import NexraChatGPT
+from .NexraDallE import NexraDallE
+from .NexraDallE2 import NexraDallE2
+from .NexraEmi import NexraEmi
+from .NexraFluxPro import NexraFluxPro
+from .NexraGeminiPro import NexraGeminiPro
+from .NexraMidjourney import NexraMidjourney
+from .NexraProdiaAI import NexraProdiaAI
+from .NexraQwen import NexraQwen
+from .NexraSD15 import NexraSD15
+from .NexraSDLora import NexraSDLora
+from .NexraSDTurbo import NexraSDTurbo
diff --git a/g4f/Provider/openai/new.py b/g4f/Provider/openai/new.py
new file mode 100644
index 00000000..f4d8e13d
--- /dev/null
+++ b/g4f/Provider/openai/new.py
@@ -0,0 +1,730 @@
+import hashlib
+import base64
+import random
+import json
+import time
+import uuid
+
+from collections import OrderedDict, defaultdict
+from typing import Any, Callable, Dict, List
+
+from datetime import (
+ datetime,
+ timedelta,
+ timezone
+)
+
+cores = [16, 24, 32]
+screens = [3000, 4000, 6000]
+maxAttempts = 500000
+
+navigator_keys = [
+ "registerProtocolHandler−function registerProtocolHandler() { [native code] }",
+ "storage−[object StorageManager]",
+ "locks−[object LockManager]",
+ "appCodeName−Mozilla",
+ "permissions−[object Permissions]",
+ "appVersion−5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36 Edg/125.0.0.0",
+ "share−function share() { [native code] }",
+ "webdriver−false",
+ "managed−[object NavigatorManagedData]",
+ "canShare−function canShare() { [native code] }",
+ "vendor−Google Inc.",
+ "vendor−Google Inc.",
+ "mediaDevices−[object MediaDevices]",
+ "vibrate−function vibrate() { [native code] }",
+ "storageBuckets−[object StorageBucketManager]",
+ "mediaCapabilities−[object MediaCapabilities]",
+ "getGamepads−function getGamepads() { [native code] }",
+ "bluetooth−[object Bluetooth]",
+ "share−function share() { [native code] }",
+ "cookieEnabled−true",
+ "virtualKeyboard−[object VirtualKeyboard]",
+ "product−Gecko",
+ "mediaDevices−[object MediaDevices]",
+ "canShare−function canShare() { [native code] }",
+ "getGamepads−function getGamepads() { [native code] }",
+ "product−Gecko",
+ "xr−[object XRSystem]",
+ "clipboard−[object Clipboard]",
+ "storageBuckets−[object StorageBucketManager]",
+ "unregisterProtocolHandler−function unregisterProtocolHandler() { [native code] }",
+ "productSub−20030107",
+ "login−[object NavigatorLogin]",
+ "vendorSub−",
+ "login−[object NavigatorLogin]",
+ "userAgent−Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36 Edg/125.0.0.0",
+ "getInstalledRelatedApps−function getInstalledRelatedApps() { [native code] }",
+ "userAgent−Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36 Edg/125.0.0.0",
+ "mediaDevices−[object MediaDevices]",
+ "locks−[object LockManager]",
+ "webkitGetUserMedia−function webkitGetUserMedia() { [native code] }",
+ "vendor−Google Inc.",
+ "xr−[object XRSystem]",
+ "mediaDevices−[object MediaDevices]",
+ "virtualKeyboard−[object VirtualKeyboard]",
+ "userAgent−Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36 Edg/125.0.0.0",
+ "virtualKeyboard−[object VirtualKeyboard]",
+ "appName−Netscape",
+ "storageBuckets−[object StorageBucketManager]",
+ "presentation−[object Presentation]",
+ "onLine−true",
+ "mimeTypes−[object MimeTypeArray]",
+ "credentials−[object CredentialsContainer]",
+ "presentation−[object Presentation]",
+ "getGamepads−function getGamepads() { [native code] }",
+ "vendorSub−",
+ "virtualKeyboard−[object VirtualKeyboard]",
+ "serviceWorker−[object ServiceWorkerContainer]",
+ "xr−[object XRSystem]",
+ "product−Gecko",
+ "keyboard−[object Keyboard]",
+ "gpu−[object GPU]",
+ "getInstalledRelatedApps−function getInstalledRelatedApps() { [native code] }",
+ "webkitPersistentStorage−[object DeprecatedStorageQuota]",
+ "doNotTrack",
+ "clearAppBadge−function clearAppBadge() { [native code] }",
+ "presentation−[object Presentation]",
+ "serial−[object Serial]",
+ "locks−[object LockManager]",
+ "requestMIDIAccess−function requestMIDIAccess() { [native code] }",
+ "locks−[object LockManager]",
+ "requestMediaKeySystemAccess−function requestMediaKeySystemAccess() { [native code] }",
+ "vendor−Google Inc.",
+ "pdfViewerEnabled−true",
+ "language−zh-CN",
+ "setAppBadge−function setAppBadge() { [native code] }",
+ "geolocation−[object Geolocation]",
+ "userAgentData−[object NavigatorUAData]",
+ "mediaCapabilities−[object MediaCapabilities]",
+ "requestMIDIAccess−function requestMIDIAccess() { [native code] }",
+ "getUserMedia−function getUserMedia() { [native code] }",
+ "mediaDevices−[object MediaDevices]",
+ "webkitPersistentStorage−[object DeprecatedStorageQuota]",
+ "userAgent−Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36 Edg/125.0.0.0",
+ "sendBeacon−function sendBeacon() { [native code] }",
+ "hardwareConcurrency−32",
+ "appVersion−5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36 Edg/125.0.0.0",
+ "credentials−[object CredentialsContainer]",
+ "storage−[object StorageManager]",
+ "cookieEnabled−true",
+ "pdfViewerEnabled−true",
+ "windowControlsOverlay−[object WindowControlsOverlay]",
+ "scheduling−[object Scheduling]",
+ "pdfViewerEnabled−true",
+ "hardwareConcurrency−32",
+ "xr−[object XRSystem]",
+ "userAgent−Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36 Edg/125.0.0.0",
+ "webdriver−false",
+ "getInstalledRelatedApps−function getInstalledRelatedApps() { [native code] }",
+ "getInstalledRelatedApps−function getInstalledRelatedApps() { [native code] }",
+ "bluetooth−[object Bluetooth]"
+]
+
+window_keys = [
+ "0",
+ "window",
+ "self",
+ "document",
+ "name",
+ "location",
+ "customElements",
+ "history",
+ "navigation",
+ "locationbar",
+ "menubar",
+ "personalbar",
+ "scrollbars",
+ "statusbar",
+ "toolbar",
+ "status",
+ "closed",
+ "frames",
+ "length",
+ "top",
+ "opener",
+ "parent",
+ "frameElement",
+ "navigator",
+ "origin",
+ "external",
+ "screen",
+ "innerWidth",
+ "innerHeight",
+ "scrollX",
+ "pageXOffset",
+ "scrollY",
+ "pageYOffset",
+ "visualViewport",
+ "screenX",
+ "screenY",
+ "outerWidth",
+ "outerHeight",
+ "devicePixelRatio",
+ "clientInformation",
+ "screenLeft",
+ "screenTop",
+ "styleMedia",
+ "onsearch",
+ "isSecureContext",
+ "trustedTypes",
+ "performance",
+ "onappinstalled",
+ "onbeforeinstallprompt",
+ "crypto",
+ "indexedDB",
+ "sessionStorage",
+ "localStorage",
+ "onbeforexrselect",
+ "onabort",
+ "onbeforeinput",
+ "onbeforematch",
+ "onbeforetoggle",
+ "onblur",
+ "oncancel",
+ "oncanplay",
+ "oncanplaythrough",
+ "onchange",
+ "onclick",
+ "onclose",
+ "oncontentvisibilityautostatechange",
+ "oncontextlost",
+ "oncontextmenu",
+ "oncontextrestored",
+ "oncuechange",
+ "ondblclick",
+ "ondrag",
+ "ondragend",
+ "ondragenter",
+ "ondragleave",
+ "ondragover",
+ "ondragstart",
+ "ondrop",
+ "ondurationchange",
+ "onemptied",
+ "onended",
+ "onerror",
+ "onfocus",
+ "onformdata",
+ "oninput",
+ "oninvalid",
+ "onkeydown",
+ "onkeypress",
+ "onkeyup",
+ "onload",
+ "onloadeddata",
+ "onloadedmetadata",
+ "onloadstart",
+ "onmousedown",
+ "onmouseenter",
+ "onmouseleave",
+ "onmousemove",
+ "onmouseout",
+ "onmouseover",
+ "onmouseup",
+ "onmousewheel",
+ "onpause",
+ "onplay",
+ "onplaying",
+ "onprogress",
+ "onratechange",
+ "onreset",
+ "onresize",
+ "onscroll",
+ "onsecuritypolicyviolation",
+ "onseeked",
+ "onseeking",
+ "onselect",
+ "onslotchange",
+ "onstalled",
+ "onsubmit",
+ "onsuspend",
+ "ontimeupdate",
+ "ontoggle",
+ "onvolumechange",
+ "onwaiting",
+ "onwebkitanimationend",
+ "onwebkitanimationiteration",
+ "onwebkitanimationstart",
+ "onwebkittransitionend",
+ "onwheel",
+ "onauxclick",
+ "ongotpointercapture",
+ "onlostpointercapture",
+ "onpointerdown",
+ "onpointermove",
+ "onpointerrawupdate",
+ "onpointerup",
+ "onpointercancel",
+ "onpointerover",
+ "onpointerout",
+ "onpointerenter",
+ "onpointerleave",
+ "onselectstart",
+ "onselectionchange",
+ "onanimationend",
+ "onanimationiteration",
+ "onanimationstart",
+ "ontransitionrun",
+ "ontransitionstart",
+ "ontransitionend",
+ "ontransitioncancel",
+ "onafterprint",
+ "onbeforeprint",
+ "onbeforeunload",
+ "onhashchange",
+ "onlanguagechange",
+ "onmessage",
+ "onmessageerror",
+ "onoffline",
+ "ononline",
+ "onpagehide",
+ "onpageshow",
+ "onpopstate",
+ "onrejectionhandled",
+ "onstorage",
+ "onunhandledrejection",
+ "onunload",
+ "crossOriginIsolated",
+ "scheduler",
+ "alert",
+ "atob",
+ "blur",
+ "btoa",
+ "cancelAnimationFrame",
+ "cancelIdleCallback",
+ "captureEvents",
+ "clearInterval",
+ "clearTimeout",
+ "close",
+ "confirm",
+ "createImageBitmap",
+ "fetch",
+ "find",
+ "focus",
+ "getComputedStyle",
+ "getSelection",
+ "matchMedia",
+ "moveBy",
+ "moveTo",
+ "open",
+ "postMessage",
+ "print",
+ "prompt",
+ "queueMicrotask",
+ "releaseEvents",
+ "reportError",
+ "requestAnimationFrame",
+ "requestIdleCallback",
+ "resizeBy",
+ "resizeTo",
+ "scroll",
+ "scrollBy",
+ "scrollTo",
+ "setInterval",
+ "setTimeout",
+ "stop",
+ "structuredClone",
+ "webkitCancelAnimationFrame",
+ "webkitRequestAnimationFrame",
+ "chrome",
+ "g_opr",
+ "opr",
+ "ethereum",
+ "caches",
+ "cookieStore",
+ "ondevicemotion",
+ "ondeviceorientation",
+ "ondeviceorientationabsolute",
+ "launchQueue",
+ "documentPictureInPicture",
+ "getScreenDetails",
+ "queryLocalFonts",
+ "showDirectoryPicker",
+ "showOpenFilePicker",
+ "showSaveFilePicker",
+ "originAgentCluster",
+ "credentialless",
+ "speechSynthesis",
+ "onscrollend",
+ "webkitRequestFileSystem",
+ "webkitResolveLocalFileSystemURL",
+ "__remixContext",
+ "__oai_SSR_TTI",
+ "__remixManifest",
+ "__reactRouterVersion",
+ "DD_RUM",
+ "__REACT_INTL_CONTEXT__",
+ "filterCSS",
+ "filterXSS",
+ "__SEGMENT_INSPECTOR__",
+ "DD_LOGS",
+ "regeneratorRuntime",
+ "_g",
+ "__remixRouteModules",
+ "__remixRouter",
+ "__STATSIG_SDK__",
+ "__STATSIG_JS_SDK__",
+ "__STATSIG_RERENDER_OVERRIDE__",
+ "_oaiHandleSessionExpired"
+]
+
+def get_parse_time():
+ now = datetime.now(timezone(timedelta(hours=-5)))
+ return now.strftime("%a %b %d %Y %H:%M:%S") + " GMT+0200 (Central European Summer Time)"
+
+def get_config(user_agent):
+
+ core = random.choice(cores)
+ screen = random.choice(screens)
+
+ # partially hardcoded config
+ config = [
+ core + screen,
+ get_parse_time(),
+ 4294705152,
+ random.random(),
+ user_agent,
+ None,
+ "remix-prod-15f1ec0f78ad898b9606a88d384ef76345b82b82", #document.documentElement.getAttribute("data-build"),
+ "en-US",
+ "en-US,es-US,en,es",
+ 0,
+ random.choice(navigator_keys),
+ 'location',
+ random.choice(window_keys),
+ time.perf_counter(),
+ str(uuid.uuid4()),
+ ]
+
+ return config
+
+
+def get_answer_token(seed, diff, config):
+ answer, solved = generate_answer(seed, diff, config)
+
+ if solved:
+ return "gAAAAAB" + answer
+ else:
+ raise Exception("Failed to solve 'gAAAAAB' challenge")
+
+def generate_answer(seed, diff, config):
+ diff_len = len(diff)
+ seed_encoded = seed.encode()
+ p1 = (json.dumps(config[:3], separators=(',', ':'), ensure_ascii=False)[:-1] + ',').encode()
+ p2 = (',' + json.dumps(config[4:9], separators=(',', ':'), ensure_ascii=False)[1:-1] + ',').encode()
+ p3 = (',' + json.dumps(config[10:], separators=(',', ':'), ensure_ascii=False)[1:]).encode()
+
+ target_diff = bytes.fromhex(diff)
+
+ for i in range(maxAttempts):
+ d1 = str(i).encode()
+ d2 = str(i >> 1).encode()
+
+ string = (
+ p1
+ + d1
+ + p2
+ + d2
+ + p3
+ )
+
+ base_encode = base64.b64encode(string)
+ hash_value = hashlib.new("sha3_512", seed_encoded + base_encode).digest()
+
+ if hash_value[:diff_len] <= target_diff:
+ return base_encode.decode(), True
+
+ return 'wQ8Lk5FbGpA2NcR9dShT6gYjU7VxZ4D' + base64.b64encode(f'"{seed}"'.encode()).decode(), False
+
+def get_requirements_token(config):
+ require, solved = generate_answer(format(random.random()), "0fffff", config)
+
+ if solved:
+ return 'gAAAAAC' + require
+ else:
+ raise Exception("Failed to solve 'gAAAAAC' challenge")
+
+
+### processing turnstile token
+
+class OrderedMap:
+ def __init__(self):
+ self.map = OrderedDict()
+
+ def add(self, key: str, value: Any):
+ self.map[key] = value
+
+ def to_json(self):
+ return json.dumps(self.map)
+
+ def __str__(self):
+ return self.to_json()
+
+
+TurnTokenList = List[List[Any]]
+FloatMap = Dict[float, Any]
+StringMap = Dict[str, Any]
+FuncType = Callable[..., Any]
+
+start_time = time.time()
+
+def get_turnstile_token(dx: str, p: str) -> str:
+ decoded_bytes = base64.b64decode(dx)
+ # print(decoded_bytes.decode())
+ return process_turnstile_token(decoded_bytes.decode(), p)
+
+
+def process_turnstile_token(dx: str, p: str) -> str:
+ result = []
+ p_length = len(p)
+ if p_length != 0:
+ for i, r in enumerate(dx):
+ result.append(chr(ord(r) ^ ord(p[i % p_length])))
+ else:
+ result = list(dx)
+ return "".join(result)
+
+
+def is_slice(input_val: Any) -> bool:
+ return isinstance(input_val, (list, tuple))
+
+
+def is_float(input_val: Any) -> bool:
+ return isinstance(input_val, float)
+
+
+def is_string(input_val: Any) -> bool:
+ return isinstance(input_val, str)
+
+
+def to_str(input_val: Any) -> str:
+ if input_val is None:
+ return "undefined"
+ elif is_float(input_val):
+ return f"{input_val:.16g}"
+ elif is_string(input_val):
+ special_cases = {
+ "window.Math": "[object Math]",
+ "window.Reflect": "[object Reflect]",
+ "window.performance": "[object Performance]",
+ "window.localStorage": "[object Storage]",
+ "window.Object": "function Object() { [native code] }",
+ "window.Reflect.set": "function set() { [native code] }",
+ "window.performance.now": "function () { [native code] }",
+ "window.Object.create": "function create() { [native code] }",
+ "window.Object.keys": "function keys() { [native code] }",
+ "window.Math.random": "function random() { [native code] }",
+ }
+ return special_cases.get(input_val, input_val)
+ elif isinstance(input_val, list) and all(
+ isinstance(item, str) for item in input_val
+ ):
+ return ",".join(input_val)
+ else:
+ # print(f"Type of input is: {type(input_val)}")
+ return str(input_val)
+
+
+def get_func_map() -> FloatMap:
+ process_map: FloatMap = defaultdict(lambda: None)
+
+ def func_1(e: float, t: float):
+ e_str = to_str(process_map[e])
+ t_str = to_str(process_map[t])
+ if e_str is not None and t_str is not None:
+ res = process_turnstile_token(e_str, t_str)
+ process_map[e] = res
+ else:
+ pass
+ # print(f"Warning: Unable to process func_1 for e={e}, t={t}")
+
+ def func_2(e: float, t: Any):
+ process_map[e] = t
+
+ def func_5(e: float, t: float):
+ n = process_map[e]
+ tres = process_map[t]
+ if n is None:
+ process_map[e] = tres
+ elif is_slice(n):
+ nt = n + [tres] if tres is not None else n
+ process_map[e] = nt
+ else:
+ if is_string(n) or is_string(tres):
+ res = to_str(n) + to_str(tres)
+ elif is_float(n) and is_float(tres):
+ res = n + tres
+ else:
+ res = "NaN"
+ process_map[e] = res
+
+ def func_6(e: float, t: float, n: float):
+ tv = process_map[t]
+ nv = process_map[n]
+ if is_string(tv) and is_string(nv):
+ res = f"{tv}.{nv}"
+ if res == "window.document.location":
+ process_map[e] = "https://chatgpt.com/"
+ else:
+ process_map[e] = res
+ else:
+ pass
+ # print("func type 6 error")
+
+ def func_24(e: float, t: float, n: float):
+ tv = process_map[t]
+ nv = process_map[n]
+ if is_string(tv) and is_string(nv):
+ process_map[e] = f"{tv}.{nv}"
+ else:
+ pass
+ # print("func type 24 error")
+
+ def func_7(e: float, *args):
+ n = [process_map[arg] for arg in args]
+ ev = process_map[e]
+ if isinstance(ev, str):
+ if ev == "window.Reflect.set":
+ obj = n[0]
+ key_str = str(n[1])
+ val = n[2]
+ obj.add(key_str, val)
+ elif callable(ev):
+ ev(*n)
+
+ def func_17(e: float, t: float, *args):
+ i = [process_map[arg] for arg in args]
+ tv = process_map[t]
+ res = None
+ if isinstance(tv, str):
+ if tv == "window.performance.now":
+ current_time = time.time_ns()
+ elapsed_ns = current_time - int(start_time * 1e9)
+ res = (elapsed_ns + random.random()) / 1e6
+ elif tv == "window.Object.create":
+ res = OrderedMap()
+ elif tv == "window.Object.keys":
+ if isinstance(i[0], str) and i[0] == "window.localStorage":
+ res = [
+ "STATSIG_LOCAL_STORAGE_INTERNAL_STORE_V4",
+ "STATSIG_LOCAL_STORAGE_STABLE_ID",
+ "client-correlated-secret",
+ "oai/apps/capExpiresAt",
+ "oai-did",
+ "STATSIG_LOCAL_STORAGE_LOGGING_REQUEST",
+ "UiState.isNavigationCollapsed.1",
+ ]
+ elif tv == "window.Math.random":
+ res = random.random()
+ elif callable(tv):
+ res = tv(*i)
+ process_map[e] = res
+
+ def func_8(e: float, t: float):
+ process_map[e] = process_map[t]
+
+ def func_14(e: float, t: float):
+ tv = process_map[t]
+ if is_string(tv):
+ try:
+ token_list = json.loads(tv)
+ process_map[e] = token_list
+ except json.JSONDecodeError:
+ # print(f"Warning: Unable to parse JSON for key {t}")
+ process_map[e] = None
+ else:
+ # print(f"Warning: Value for key {t} is not a string")
+ process_map[e] = None
+
+ def func_15(e: float, t: float):
+ tv = process_map[t]
+ process_map[e] = json.dumps(tv)
+
+ def func_18(e: float):
+ ev = process_map[e]
+ e_str = to_str(ev)
+ decoded = base64.b64decode(e_str).decode()
+ process_map[e] = decoded
+
+ def func_19(e: float):
+ ev = process_map[e]
+ e_str = to_str(ev)
+ encoded = base64.b64encode(e_str.encode()).decode()
+ process_map[e] = encoded
+
+ def func_20(e: float, t: float, n: float, *args):
+ o = [process_map[arg] for arg in args]
+ ev = process_map[e]
+ tv = process_map[t]
+ if ev == tv:
+ nv = process_map[n]
+ if callable(nv):
+ nv(*o)
+ else:
+ pass
+ # print("func type 20 error")
+
+ def func_21(*args):
+ pass
+
+ def func_23(e: float, t: float, *args):
+ i = list(args)
+ ev = process_map[e]
+ tv = process_map[t]
+ if ev is not None and callable(tv):
+ tv(*i)
+
+ process_map.update(
+ {
+ 1: func_1,
+ 2: func_2,
+ 5: func_5,
+ 6: func_6,
+ 7: func_7,
+ 8: func_8,
+ 10: "window",
+ 14: func_14,
+ 15: func_15,
+ 17: func_17,
+ 18: func_18,
+ 19: func_19,
+ 20: func_20,
+ 21: func_21,
+ 23: func_23,
+ 24: func_24,
+ }
+ )
+
+ return process_map
+
+
+def process_turnstile(dx: str, p: str) -> str:
+ tokens = get_turnstile_token(dx, p)
+ res = ""
+ token_list = json.loads(tokens)
+ process_map = get_func_map()
+
+ def func_3(e: str):
+ nonlocal res
+ res = base64.b64encode(e.encode()).decode()
+
+ process_map[3] = func_3
+ process_map[9] = token_list
+ process_map[16] = p
+
+ for token in token_list:
+ try:
+ e = token[0]
+ t = token[1:]
+ f = process_map.get(e)
+ if callable(f):
+ f(*t)
+ else:
+ pass
+ # print(f"Warning: No function found for key {e}")
+ except Exception as exc:
+ raise Exception(f"Error processing token {token}: {exc}")
+ # print(f"Error processing token {token}: {exc}")
+
+ return res \ No newline at end of file
diff --git a/g4f/Provider/selenium/Bard.py b/g4f/Provider/selenium/Bard.py
deleted file mode 100644
index 9c809128..00000000
--- a/g4f/Provider/selenium/Bard.py
+++ /dev/null
@@ -1,80 +0,0 @@
-from __future__ import annotations
-
-import time
-import os
-
-try:
- from selenium.webdriver.common.by import By
- from selenium.webdriver.support.ui import WebDriverWait
- from selenium.webdriver.support import expected_conditions as EC
-except ImportError:
- pass
-
-from ...typing import CreateResult, Messages
-from ..base_provider import AbstractProvider
-from ..helper import format_prompt
-from ...webdriver import WebDriver, WebDriverSession, element_send_text
-
-
-class Bard(AbstractProvider):
- url = "https://bard.google.com"
- working = False
- needs_auth = True
- webdriver = True
-
- @classmethod
- def create_completion(
- cls,
- model: str,
- messages: Messages,
- stream: bool,
- proxy: str = None,
- webdriver: WebDriver = None,
- user_data_dir: str = None,
- headless: bool = True,
- **kwargs
- ) -> CreateResult:
- prompt = format_prompt(messages)
- session = WebDriverSession(webdriver, user_data_dir, headless, proxy=proxy)
- with session as driver:
- try:
- driver.get(f"{cls.url}/chat")
- wait = WebDriverWait(driver, 10 if headless else 240)
- wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "div.ql-editor.textarea")))
- except:
- # Reopen browser for login
- if not webdriver:
- driver = session.reopen()
- driver.get(f"{cls.url}/chat")
- login_url = os.environ.get("G4F_LOGIN_URL")
- if login_url:
- yield f"Please login: [Google Bard]({login_url})\n\n"
- wait = WebDriverWait(driver, 240)
- wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "div.ql-editor.textarea")))
- else:
- raise RuntimeError("Prompt textarea not found. You may not be logged in.")
-
- # Add hook in XMLHttpRequest
- script = """
-const _http_request_open = XMLHttpRequest.prototype.open;
-window._message = "";
-XMLHttpRequest.prototype.open = function(method, url) {
- if (url.includes("/assistant.lamda.BardFrontendService/StreamGenerate")) {
- this.addEventListener("load", (event) => {
- window._message = JSON.parse(JSON.parse(this.responseText.split("\\n")[3])[0][2])[4][0][1][0];
- });
- }
- return _http_request_open.call(this, method, url);
-}
-"""
- driver.execute_script(script)
-
- element_send_text(driver.find_element(By.CSS_SELECTOR, "div.ql-editor.textarea"), prompt)
-
- while True:
- chunk = driver.execute_script("return window._message;")
- if chunk:
- yield chunk
- return
- else:
- time.sleep(0.1) \ No newline at end of file
diff --git a/g4f/Provider/selenium/MyShell.py b/g4f/Provider/selenium/MyShell.py
index a3f246ff..02e182d4 100644
--- a/g4f/Provider/selenium/MyShell.py
+++ b/g4f/Provider/selenium/MyShell.py
@@ -9,7 +9,7 @@ from ...webdriver import WebDriver, WebDriverSession, bypass_cloudflare
class MyShell(AbstractProvider):
url = "https://app.myshell.ai/chat"
- working = True
+ working = False
supports_gpt_35_turbo = True
supports_stream = True
@@ -73,4 +73,4 @@ return content;
elif chunk != "":
break
else:
- time.sleep(0.1) \ No newline at end of file
+ time.sleep(0.1)
diff --git a/g4f/Provider/selenium/PerplexityAi.py b/g4f/Provider/selenium/PerplexityAi.py
index 6b529d5b..d965dbf7 100644
--- a/g4f/Provider/selenium/PerplexityAi.py
+++ b/g4f/Provider/selenium/PerplexityAi.py
@@ -16,7 +16,7 @@ from ...webdriver import WebDriver, WebDriverSession, element_send_text
class PerplexityAi(AbstractProvider):
url = "https://www.perplexity.ai"
- working = True
+ working = False
supports_gpt_35_turbo = True
supports_stream = True
@@ -105,4 +105,4 @@ if(window._message && window._message != window._last_message) {
elif chunk != "":
break
else:
- time.sleep(0.1) \ No newline at end of file
+ time.sleep(0.1)
diff --git a/g4f/Provider/selenium/TalkAi.py b/g4f/Provider/selenium/TalkAi.py
index 89280598..a7b63375 100644
--- a/g4f/Provider/selenium/TalkAi.py
+++ b/g4f/Provider/selenium/TalkAi.py
@@ -8,7 +8,7 @@ from ...webdriver import WebDriver, WebDriverSession
class TalkAi(AbstractProvider):
url = "https://talkai.info"
- working = True
+ working = False
supports_gpt_35_turbo = True
supports_stream = True
@@ -83,4 +83,4 @@ return content;
elif chunk != "":
break
else:
- time.sleep(0.1) \ No newline at end of file
+ time.sleep(0.1)
diff --git a/g4f/Provider/selenium/__init__.py b/g4f/Provider/selenium/__init__.py
index 1b801725..3a59ea58 100644
--- a/g4f/Provider/selenium/__init__.py
+++ b/g4f/Provider/selenium/__init__.py
@@ -2,4 +2,3 @@ from .MyShell import MyShell
from .PerplexityAi import PerplexityAi
from .Phind import Phind
from .TalkAi import TalkAi
-from .Bard import Bard \ No newline at end of file
diff --git a/g4f/Provider/unfinished/AiChatting.py b/g4f/Provider/unfinished/AiChatting.py
deleted file mode 100644
index f062fa98..00000000
--- a/g4f/Provider/unfinished/AiChatting.py
+++ /dev/null
@@ -1,66 +0,0 @@
-from __future__ import annotations
-
-from urllib.parse import unquote
-
-from ...typing import AsyncResult, Messages
-from ..base_provider import AbstractProvider
-from ...webdriver import WebDriver
-from ...requests import Session, get_session_from_browser
-
-class AiChatting(AbstractProvider):
- url = "https://www.aichatting.net"
- supports_gpt_35_turbo = True
- _session: Session = None
-
- @classmethod
- def create_completion(
- cls,
- model: str,
- messages: Messages,
- stream: bool,
- proxy: str = None,
- timeout: int = 120,
- webdriver: WebDriver = None,
- **kwargs
- ) -> AsyncResult:
- if not cls._session:
- cls._session = get_session_from_browser(cls.url, webdriver, proxy, timeout)
- visitorId = unquote(cls._session.cookies.get("aichatting.website.visitorId"))
-
- headers = {
- "accept": "application/json, text/plain, */*",
- "lang": "en",
- "source": "web"
- }
- data = {
- "roleId": 0,
- }
- try:
- response = cls._session.post("https://aga-api.aichatting.net/aigc/chat/record/conversation/create", json=data, headers=headers)
- response.raise_for_status()
- conversation_id = response.json()["data"]["conversationId"]
- except Exception as e:
- cls.reset()
- raise e
- headers = {
- "authority": "aga-api.aichatting.net",
- "accept": "text/event-stream,application/json, text/event-stream",
- "lang": "en",
- "source": "web",
- "vtoken": visitorId,
- }
- data = {
- "spaceHandle": True,
- "roleId": 0,
- "messages": messages,
- "conversationId": conversation_id,
- }
- response = cls._session.post("https://aga-api.aichatting.net/aigc/chat/v2/stream", json=data, headers=headers, stream=True)
- response.raise_for_status()
- for chunk in response.iter_lines():
- if chunk.startswith(b"data:"):
- yield chunk[5:].decode().replace("-=- --", " ").replace("-=-n--", "\n").replace("--@DONE@--", "")
-
- @classmethod
- def reset(cls):
- cls._session = None \ No newline at end of file
diff --git a/g4f/Provider/unfinished/ChatAiGpt.py b/g4f/Provider/unfinished/ChatAiGpt.py
deleted file mode 100644
index bc962623..00000000
--- a/g4f/Provider/unfinished/ChatAiGpt.py
+++ /dev/null
@@ -1,68 +0,0 @@
-from __future__ import annotations
-
-import re
-from aiohttp import ClientSession
-
-from ...typing import AsyncResult, Messages
-from ..base_provider import AsyncGeneratorProvider
-from ..helper import format_prompt
-
-
-class ChatAiGpt(AsyncGeneratorProvider):
- url = "https://chataigpt.org"
- supports_gpt_35_turbo = True
- _nonce = None
- _post_id = None
-
- @classmethod
- async def create_async_generator(
- cls,
- model: str,
- messages: Messages,
- proxy: str = None,
- **kwargs
- ) -> AsyncResult:
- headers = {
- "User-Agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/118.0",
- "Accept": "*/*",
- "Accept-Language": "de,en-US;q=0.7,en;q=0.3",
- "Accept-Encoding": "gzip, deflate, br",
- "Origin": cls.url,
- "Alt-Used": cls.url,
- "Connection": "keep-alive",
- "Referer": cls.url,
- "Pragma": "no-cache",
- "Cache-Control": "no-cache",
- "TE": "trailers",
- "Sec-Fetch-Dest": "empty",
- "Sec-Fetch-Mode": "cors",
- "Sec-Fetch-Site": "same-origin",
- }
- async with ClientSession(headers=headers) as session:
- if not cls._nonce:
- async with session.get(f"{cls.url}/", proxy=proxy) as response:
- response.raise_for_status()
- response = await response.text()
-
- result = re.search(
- r'data-nonce=(.*?) data-post-id=([0-9]+)', response
- )
-
- if result:
- cls._nonce, cls._post_id = result.group(1), result.group(2)
- else:
- raise RuntimeError("No nonce found")
- prompt = format_prompt(messages)
- data = {
- "_wpnonce": cls._nonce,
- "post_id": cls._post_id,
- "url": cls.url,
- "action": "wpaicg_chat_shortcode_message",
- "message": prompt,
- "bot_id": 0
- }
- async with session.post(f"{cls.url}/wp-admin/admin-ajax.php", data=data, proxy=proxy) as response:
- response.raise_for_status()
- async for chunk in response.content:
- if chunk:
- yield chunk.decode() \ No newline at end of file
diff --git a/g4f/Provider/unfinished/Komo.py b/g4f/Provider/unfinished/Komo.py
deleted file mode 100644
index 84d8d634..00000000
--- a/g4f/Provider/unfinished/Komo.py
+++ /dev/null
@@ -1,44 +0,0 @@
-from __future__ import annotations
-
-import json
-
-from ...requests import StreamSession
-from ...typing import AsyncGenerator
-from ..base_provider import AsyncGeneratorProvider, format_prompt
-
-class Komo(AsyncGeneratorProvider):
- url = "https://komo.ai/api/ask"
- supports_gpt_35_turbo = True
-
- @classmethod
- async def create_async_generator(
- cls,
- model: str,
- messages: list[dict[str, str]],
- **kwargs
- ) -> AsyncGenerator:
- async with StreamSession(impersonate="chrome107") as session:
- prompt = format_prompt(messages)
- data = {
- "query": prompt,
- "FLAG_URLEXTRACT": "false",
- "token": "",
- "FLAG_MODELA": "1",
- }
- headers = {
- 'authority': 'komo.ai',
- 'accept': 'text/event-stream',
- 'cache-control': 'no-cache',
- 'referer': 'https://komo.ai/',
- }
-
- async with session.get(cls.url, params=data, headers=headers) as response:
- response.raise_for_status()
- next = False
- async for line in response.iter_lines():
- if line == b"event: line":
- next = True
- elif next and line.startswith(b"data: "):
- yield json.loads(line[6:])
- next = False
-
diff --git a/g4f/Provider/unfinished/MikuChat.py b/g4f/Provider/unfinished/MikuChat.py
deleted file mode 100644
index bf19631f..00000000
--- a/g4f/Provider/unfinished/MikuChat.py
+++ /dev/null
@@ -1,97 +0,0 @@
-from __future__ import annotations
-
-import random, json
-from datetime import datetime
-from ...requests import StreamSession
-
-from ...typing import AsyncGenerator
-from ..base_provider import AsyncGeneratorProvider
-
-
-class MikuChat(AsyncGeneratorProvider):
- url = "https://ai.okmiku.com"
- supports_gpt_35_turbo = True
-
- @classmethod
- async def create_async_generator(
- cls,
- model: str,
- messages: list[dict[str, str]],
- **kwargs
- ) -> AsyncGenerator:
- if not model:
- model = "gpt-3.5-turbo"
- headers = {
- "authority": "api.catgpt.cc",
- "accept": "application/json",
- "origin": cls.url,
- "referer": f"{cls.url}/chat/",
- 'x-app-version': 'undefined',
- 'x-date': get_datetime(),
- 'x-fingerprint': get_fingerprint(),
- 'x-platform': 'web'
- }
- async with StreamSession(headers=headers, impersonate="chrome107") as session:
- data = {
- "model": model,
- "top_p": 0.8,
- "temperature": 0.5,
- "presence_penalty": 1,
- "frequency_penalty": 0,
- "max_tokens": 2000,
- "stream": True,
- "messages": messages,
- }
- async with session.post("https://api.catgpt.cc/ai/v1/chat/completions", json=data) as response:
- print(await response.text())
- response.raise_for_status()
- async for line in response.iter_lines():
- if line.startswith(b"data: "):
- line = json.loads(line[6:])
- chunk = line["choices"][0]["delta"].get("content")
- if chunk:
- yield chunk
-
-def k(e: str, t: int):
- a = len(e) & 3
- s = len(e) - a
- i = t
- c = 3432918353
- o = 461845907
- n = 0
- r = 0
- while n < s:
- r = (ord(e[n]) & 255) | ((ord(e[n + 1]) & 255) << 8) | ((ord(e[n + 2]) & 255) << 16) | ((ord(e[n + 3]) & 255) << 24)
- n += 4
- r = (r & 65535) * c + (((r >> 16) * c & 65535) << 16) & 4294967295
- r = (r << 15) | (r >> 17)
- r = (r & 65535) * o + (((r >> 16) * o & 65535) << 16) & 4294967295
- i ^= r
- i = (i << 13) | (i >> 19)
- l = (i & 65535) * 5 + (((i >> 16) * 5 & 65535) << 16) & 4294967295
- i = (l & 65535) + 27492 + (((l >> 16) + 58964 & 65535) << 16)
-
- if a == 3:
- r ^= (ord(e[n + 2]) & 255) << 16
- elif a == 2:
- r ^= (ord(e[n + 1]) & 255) << 8
- elif a == 1:
- r ^= ord(e[n]) & 255
- r = (r & 65535) * c + (((r >> 16) * c & 65535) << 16) & 4294967295
- r = (r << 15) | (r >> 17)
- r = (r & 65535) * o + (((r >> 16) * o & 65535) << 16) & 4294967295
- i ^= r
-
- i ^= len(e)
- i ^= i >> 16
- i = (i & 65535) * 2246822507 + (((i >> 16) * 2246822507 & 65535) << 16) & 4294967295
- i ^= i >> 13
- i = (i & 65535) * 3266489909 + (((i >> 16) * 3266489909 & 65535) << 16) & 4294967295
- i ^= i >> 16
- return i & 0xFFFFFFFF
-
-def get_fingerprint() -> str:
- return str(k(str(int(random.random() * 100000)), 256))
-
-def get_datetime() -> str:
- return datetime.now().strftime("%Y-%m-%d %H:%M:%S") \ No newline at end of file
diff --git a/g4f/Provider/unfinished/__init__.py b/g4f/Provider/unfinished/__init__.py
deleted file mode 100644
index eb5e8825..00000000
--- a/g4f/Provider/unfinished/__init__.py
+++ /dev/null
@@ -1,4 +0,0 @@
-from .MikuChat import MikuChat
-from .Komo import Komo
-from .ChatAiGpt import ChatAiGpt
-from .AiChatting import AiChatting \ No newline at end of file