summaryrefslogtreecommitdiffstats
path: root/g4f
diff options
context:
space:
mode:
Diffstat (limited to 'g4f')
-rw-r--r--g4f/Provider/AI365VIP.py4
-rw-r--r--g4f/Provider/AIChatFree.py76
-rw-r--r--g4f/Provider/AiChatOnline.py2
-rw-r--r--g4f/Provider/Airforce.py242
-rw-r--r--g4f/Provider/Aura.py4
-rw-r--r--g4f/Provider/Bixin123.py9
-rw-r--r--g4f/Provider/Blackbox.py195
-rw-r--r--g4f/Provider/ChatGpt.py206
-rw-r--r--g4f/Provider/ChatGptEs.py85
-rw-r--r--g4f/Provider/ChatHub.py84
-rw-r--r--g4f/Provider/Chatgpt4o.py8
-rw-r--r--g4f/Provider/CodeNews.py94
-rw-r--r--g4f/Provider/DDG.py163
-rw-r--r--g4f/Provider/DeepInfraChat.py142
-rw-r--r--g4f/Provider/DeepInfraImage.py5
-rw-r--r--g4f/Provider/FlowGpt.py2
-rw-r--r--g4f/Provider/FluxAirforce.py82
-rw-r--r--g4f/Provider/GPROChat.py67
-rw-r--r--g4f/Provider/GptTalkRu.py59
-rw-r--r--g4f/Provider/HuggingChat.py27
-rw-r--r--g4f/Provider/HuggingFace.py27
-rw-r--r--g4f/Provider/Koala.py11
-rw-r--r--g4f/Provider/Liaobots.py78
-rw-r--r--g4f/Provider/LiteIcoding.py29
-rw-r--r--g4f/Provider/Llama.py91
-rw-r--r--g4f/Provider/MagickPen.py155
-rw-r--r--g4f/Provider/Nexra.py173
-rw-r--r--g4f/Provider/PerplexityLabs.py11
-rw-r--r--g4f/Provider/Pi.py1
-rw-r--r--g4f/Provider/Prodia.py149
-rw-r--r--g4f/Provider/ReplicateHome.py213
-rw-r--r--g4f/Provider/Rocks.py70
-rw-r--r--g4f/Provider/Snova.py133
-rw-r--r--g4f/Provider/TwitterBio.py103
-rw-r--r--g4f/Provider/Upstage.py3
-rw-r--r--g4f/Provider/Vercel.py104
-rw-r--r--g4f/Provider/__init__.py18
-rw-r--r--g4f/Provider/bing/conversation.py6
-rw-r--r--g4f/Provider/needs_auth/Gemini.py3
-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.py82
-rw-r--r--g4f/Provider/nexra/NexraChatGPT.py66
-rw-r--r--g4f/Provider/nexra/NexraChatGPT4o.py52
-rw-r--r--g4f/Provider/nexra/NexraChatGPTWeb.py53
-rw-r--r--g4f/Provider/nexra/NexraGeminiPro.py52
-rw-r--r--g4f/Provider/nexra/NexraImageURL.py46
-rw-r--r--g4f/Provider/nexra/NexraLlama.py52
-rw-r--r--g4f/Provider/nexra/NexraQwen.py52
-rw-r--r--g4f/Provider/nexra/__init__.py1
-rw-r--r--g4f/Provider/openai/new.py730
-rw-r--r--g4f/Provider/selenium/AItianhuSpace.py116
-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__.py2
-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
-rw-r--r--g4f/client/async_client.py359
-rw-r--r--g4f/gui/client/static/css/style.css3
-rw-r--r--g4f/models.py588
68 files changed, 3419 insertions, 2159 deletions
diff --git a/g4f/Provider/AI365VIP.py b/g4f/Provider/AI365VIP.py
index 2dcc8d1c..154cbd34 100644
--- a/g4f/Provider/AI365VIP.py
+++ b/g4f/Provider/AI365VIP.py
@@ -16,11 +16,11 @@ class AI365VIP(AsyncGeneratorProvider, ProviderModelMixin):
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/AiChatOnline.py b/g4f/Provider/AiChatOnline.py
index 152a7d31..40f77105 100644
--- a/g4f/Provider/AiChatOnline.py
+++ b/g4f/Provider/AiChatOnline.py
@@ -12,10 +12,8 @@ class AiChatOnline(AsyncGeneratorProvider, ProviderModelMixin):
url = "https://aichatonlineorg.erweima.ai"
api_endpoint = "/aichatonline/api/chat/gpt"
working = True
- supports_gpt_35_turbo = True
supports_gpt_4 = True
default_model = 'gpt-4o-mini'
- supports_message_history = False
@classmethod
async def grab_token(
diff --git a/g4f/Provider/Airforce.py b/g4f/Provider/Airforce.py
new file mode 100644
index 00000000..51f8ba55
--- /dev/null
+++ b/g4f/Provider/Airforce.py
@@ -0,0 +1,242 @@
+from __future__ import annotations
+
+from aiohttp import ClientSession, ClientResponseError
+import json
+from ..typing import AsyncResult, Messages
+from .base_provider import AsyncGeneratorProvider, ProviderModelMixin
+from ..image import ImageResponse
+from .helper import format_prompt
+from ..errors import ResponseStatusError
+
+class Airforce(AsyncGeneratorProvider, ProviderModelMixin):
+ url = "https://api.airforce"
+ text_api_endpoint = "https://api.airforce/chat/completions"
+ image_api_endpoint = "https://api.airforce/imagine2"
+ working = True
+ supports_gpt_35_turbo = True
+ supports_gpt_4 = True
+ 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',
+ ]
+
+ image_models = [
+ 'flux',
+ 'flux-realism',
+ 'flux-anime',
+ 'flux-3d',
+ 'flux-disney',
+ 'flux-pixel',
+ 'flux-4o',
+ 'any-dark',
+ 'dall-e-3',
+ ]
+
+ models = [
+ *text_models,
+ *image_models
+ ]
+ model_aliases = {
+ # Open source models
+ "llama-2-13b": "llama-2-13b-chat",
+ "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",
+ "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",
+
+ # Image models
+ "dalle-3": "dall-e-3",
+ }
+
+ @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": "https://api.airforce",
+ "user-agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36",
+ "authorization": "Bearer null",
+ "cache-control": "no-cache",
+ "pragma": "no-cache",
+ "priority": "u=1, i",
+ "referer": "https://llmplayground.net/",
+ "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": "cross-site",
+ }
+
+ 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
+
+ @classmethod
+ async def generate_text(cls, model: str, messages: Messages, headers: dict, proxy: str, **kwargs) -> AsyncResult:
+ async with ClientSession() as session:
+ data = {
+ "messages": [{"role": "user", "content": message['content']} for message in messages],
+ "model": model,
+ "max_tokens": kwargs.get('max_tokens', 4096),
+ "temperature": kwargs.get('temperature', 1),
+ "top_p": kwargs.get('top_p', 1),
+ "stream": True
+ }
+
+ try:
+ async with session.post(cls.text_api_endpoint, json=data, headers=headers, 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: "):
+ if line == "data: [DONE]":
+ break
+ 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:
+ content = delta['content']
+ if "One message exceeds the 1000chars per message limit" in content:
+ raise ResponseStatusError(
+ "Message too long",
+ 400,
+ "Please try a shorter message."
+ )
+ yield content
+ except json.JSONDecodeError:
+ continue
+ except ResponseStatusError as e:
+ raise e
+ except Exception as e:
+ raise ResponseStatusError(str(e), 500, "An unexpected error occurred")
+
+ @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
+ }
+ 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:
+ response.raise_for_status()
+ content = await response.read()
+
+ if response.content_type.startswith('image/'):
+ image_url = str(response.url)
+ yield ImageResponse(image_url, prompt)
+ else:
+ try:
+ text = content.decode('utf-8', errors='ignore')
+ raise ResponseStatusError("Image generation failed", response.status, text)
+ except Exception as decode_error:
+ raise ResponseStatusError("Decoding error", 500, str(decode_error))
+ except ClientResponseError as e:
+ raise ResponseStatusError(f"HTTP {e.status}", e.status, e.message)
+ except Exception as e:
+ raise ResponseStatusError("Unexpected error", 500, str(e))
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/Bixin123.py b/g4f/Provider/Bixin123.py
index 694a2eff..081064f9 100644
--- a/g4f/Provider/Bixin123.py
+++ b/g4f/Provider/Bixin123.py
@@ -2,6 +2,7 @@ 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
@@ -14,7 +15,7 @@ class Bixin123(AsyncGeneratorProvider, ProviderModelMixin):
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']
+ models = ['gpt-3.5-turbo', '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",
@@ -31,6 +32,10 @@ class Bixin123(AsyncGeneratorProvider, ProviderModelMixin):
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,
@@ -45,7 +50,7 @@ class Bixin123(AsyncGeneratorProvider, ProviderModelMixin):
"accept-language": "en-US,en;q=0.9",
"cache-control": "no-cache",
"content-type": "application/json",
- "fingerprint": "988148794",
+ "fingerprint": cls.generate_fingerprint(),
"origin": cls.url,
"pragma": "no-cache",
"priority": "u=1, i",
diff --git a/g4f/Provider/Blackbox.py b/g4f/Provider/Blackbox.py
index 9fab4a09..3e183076 100644
--- a/g4f/Provider/Blackbox.py
+++ b/g4f/Provider/Blackbox.py
@@ -1,156 +1,159 @@
from __future__ import annotations
-import uuid
-import secrets
import re
-import base64
+import random
+import string
from aiohttp import ClientSession
-from typing import AsyncGenerator, Optional
from ..typing import AsyncResult, Messages, ImageType
-from ..image import to_data_uri, ImageResponse
+from ..image import ImageResponse, to_data_uri
from .base_provider import AsyncGeneratorProvider, ProviderModelMixin
class Blackbox(AsyncGeneratorProvider, ProviderModelMixin):
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'
models = [
- default_model,
- "gemini-1.5-flash",
+ 'blackbox',
+ 'gemini-1.5-flash',
"llama-3.1-8b",
'llama-3.1-70b',
'llama-3.1-405b',
- 'ImageGeneration',
+ 'ImageGenerationLV45LJp',
+ 'GPT-4o',
+ 'Gemini-PRO',
+ 'Claude-Sonnet-3.5',
]
model_aliases = {
"gemini-flash": "gemini-1.5-flash",
+ "flux": "ImageGenerationLV45LJp",
+ "gpt-4o": "GPT-4o",
+ "gemini-pro": "Gemini-PRO",
+ "claude-3.5-sonnet": "Claude-Sonnet-3.5",
}
-
- agent_mode_map = {
- 'ImageGeneration': {"mode": True, "id": "ImageGenerationLV45LJp", "name": "Image Generation"},
+
+ agentMode = {
+ 'ImageGenerationLV45LJp': {'mode': True, 'id': "ImageGenerationLV45LJp", 'name': "Image Generation"},
}
- model_id_map = {
+ trendingAgentMode = {
"blackbox": {},
"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"}
+ 'llama-3.1-405b': {'mode': True, 'id': "llama-3.1-405b"},
+ }
+
+ userSelectedModel = {
+ "GPT-4o": "GPT-4o",
+ "Gemini-PRO": "Gemini-PRO",
+ 'Claude-Sonnet-3.5': "Claude-Sonnet-3.5",
}
@classmethod
def get_model(cls, model: str) -> str:
if model in cls.models:
return model
+ elif model in cls.userSelectedModel:
+ return model
elif model in cls.model_aliases:
return cls.model_aliases[model]
else:
return cls.default_model
@classmethod
- async def download_image_to_base64_url(cls, url: str) -> str:
- async with ClientSession() as session:
- async with session.get(url) as response:
- image_data = await response.read()
- base64_data = base64.b64encode(image_data).decode('utf-8')
- mime_type = response.headers.get('Content-Type', 'image/jpeg')
- return f"data:{mime_type};base64,{base64_data}"
-
- @classmethod
async def create_async_generator(
cls,
model: str,
messages: Messages,
- proxy: Optional[str] = None,
- image: Optional[ImageType] = None,
- image_name: Optional[str] = None,
+ proxy: str = None,
+ image: ImageType = None,
+ image_name: str = None,
**kwargs
- ) -> AsyncGenerator[AsyncResult, None]:
- if image is not None:
- messages[-1]["data"] = {
- "fileText": image_name,
- "imageBase64": to_data_uri(image),
- "title": str(uuid.uuid4())
- }
-
+ ) -> AsyncResult:
+ model = cls.get_model(model)
+
headers = {
- "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36",
- "Accept": "*/*",
- "Accept-Language": "en-US,en;q=0.5",
- "Accept-Encoding": "gzip, deflate, br",
- "Referer": cls.url,
- "Content-Type": "application/json",
- "Origin": cls.url,
- "DNT": "1",
- "Sec-GPC": "1",
- "Alt-Used": "www.blackbox.ai",
- "Connection": "keep-alive",
+ "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"
}
+ if model in cls.userSelectedModel:
+ prefix = f"@{cls.userSelectedModel[model]}"
+ if not messages[0]['content'].startswith(prefix):
+ messages[0]['content'] = f"{prefix} {messages[0]['content']}"
+
async with ClientSession(headers=headers) as session:
- random_id = secrets.token_hex(16)
- random_user_id = str(uuid.uuid4())
-
- model = cls.get_model(model) # Resolve the model alias
+ if image is not None:
+ messages[-1]["data"] = {
+ "fileText": image_name,
+ "imageBase64": to_data_uri(image)
+ }
+ random_id = ''.join(random.choices(string.ascii_letters + string.digits, k=7))
+
data = {
"messages": messages,
"id": random_id,
- "userId": random_user_id,
+ "previewToken": None,
+ "userId": None,
"codeModelMode": True,
- "agentMode": cls.agent_mode_map.get(model, {}),
+ "agentMode": {},
"trendingAgentMode": {},
+ "userSelectedModel": None,
"isMicMode": False,
+ "maxTokens": 99999999,
+ "playgroundTopP": 0.9,
+ "playgroundTemperature": 0.5,
"isChromeExt": False,
- "playgroundMode": False,
- "webSearchMode": False,
- "userSystemPrompt": "",
"githubToken": None,
- "trendingAgentModel": cls.model_id_map.get(model, {}),
- "maxTokens": None
+ "clickedAnswer2": False,
+ "clickedAnswer3": False,
+ "clickedForceWebSearch": False,
+ "visitFromDelta": False,
+ "mobileClient": False,
+ "webSearchMode": False,
}
- async with session.post(
- f"{cls.url}/api/chat", json=data, proxy=proxy
- ) as response:
+ if model in cls.agentMode:
+ data["agentMode"] = cls.agentMode[model]
+ elif model in cls.trendingAgentMode:
+ data["trendingAgentMode"] = cls.trendingAgentMode[model]
+ elif model in cls.userSelectedModel:
+ data["userSelectedModel"] = cls.userSelectedModel[model]
+
+ async with session.post(cls.api_endpoint, json=data, proxy=proxy) as response:
response.raise_for_status()
- full_response = ""
- buffer = ""
- image_base64_url = None
- async for chunk in response.content.iter_any():
- if chunk:
- decoded_chunk = chunk.decode()
- cleaned_chunk = re.sub(r'\$@\$.+?\$@\$|\$@\$', '', decoded_chunk)
-
- buffer += cleaned_chunk
-
- # Check if there's a complete image line in the buffer
- image_match = re.search(r'!\[Generated Image\]\((https?://[^\s\)]+)\)', buffer)
- if image_match:
- image_url = image_match.group(1)
- # Download the image and convert to base64 URL
- image_base64_url = await cls.download_image_to_base64_url(image_url)
-
- # Remove the image line from the buffer
- buffer = re.sub(r'!\[Generated Image\]\(https?://[^\s\)]+\)', '', buffer)
-
- # Send text line by line
- lines = buffer.split('\n')
- for line in lines[:-1]:
- if line.strip():
- full_response += line + '\n'
- yield line + '\n'
- buffer = lines[-1] # Keep the last incomplete line in the buffer
-
- # Send the remaining buffer if it's not empty
- if buffer.strip():
- full_response += buffer
- yield buffer
-
- # If an image was found, send it as ImageResponse
- if image_base64_url:
- alt_text = "Generated Image"
- image_response = ImageResponse(image_base64_url, alt=alt_text)
- yield image_response
+ 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'])
+ else:
+ raise Exception("Image URL not found in the response")
+ else:
+ async for chunk in response.content.iter_any():
+ if chunk:
+ decoded_chunk = chunk.decode()
+ decoded_chunk = re.sub(r'\$@\$v=[^$]+\$@\$', '', decoded_chunk)
+ if decoded_chunk.strip():
+ yield decoded_chunk
diff --git a/g4f/Provider/ChatGpt.py b/g4f/Provider/ChatGpt.py
new file mode 100644
index 00000000..fc34fc2b
--- /dev/null
+++ b/g4f/Provider/ChatGpt.py
@@ -0,0 +1,206 @@
+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}).json()
+
+ turnstile = response.get('turnstile', {})
+ turnstile_required = turnstile.get('required')
+ pow_conf = response.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.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),
+ },
+ }
+
+ 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:
+ if 'DONE' in line.decode():
+ break
+
+ data = json.loads(line.decode()[6:])
+ 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..0e7062e5
--- /dev/null
+++ b/g4f/Provider/ChatGptEs.py
@@ -0,0 +1,85 @@
+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_gpt_4 = 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/Chatgpt4o.py b/g4f/Provider/Chatgpt4o.py
index f3dc8a15..d38afb7d 100644
--- a/g4f/Provider/Chatgpt4o.py
+++ b/g4f/Provider/Chatgpt4o.py
@@ -13,7 +13,13 @@ class Chatgpt4o(AsyncProvider, ProviderModelMixin):
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/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..1eae7b39 100644
--- a/g4f/Provider/DDG.py
+++ b/g4f/Provider/DDG.py
@@ -2,115 +2,108 @@ 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_gpt_4 = 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/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/FlowGpt.py b/g4f/Provider/FlowGpt.py
index d823a7ab..d510eabe 100644
--- a/g4f/Provider/FlowGpt.py
+++ b/g4f/Provider/FlowGpt.py
@@ -12,7 +12,7 @@ from ..requests.raise_for_status import raise_for_status
class FlowGpt(AsyncGeneratorProvider, ProviderModelMixin):
url = "https://flowgpt.com/chat"
- working = True
+ working = False
supports_gpt_35_turbo = True
supports_message_history = True
supports_system_message = True
diff --git a/g4f/Provider/FluxAirforce.py b/g4f/Provider/FluxAirforce.py
deleted file mode 100644
index fe003a61..00000000
--- a/g4f/Provider/FluxAirforce.py
+++ /dev/null
@@ -1,82 +0,0 @@
-from __future__ import annotations
-
-from aiohttp import ClientSession, ClientResponseError
-from urllib.parse import urlencode
-import io
-
-from ..typing import AsyncResult, Messages
-from .base_provider import AsyncGeneratorProvider, ProviderModelMixin
-from ..image import ImageResponse, is_accepted_format
-
-class FluxAirforce(AsyncGeneratorProvider, ProviderModelMixin):
- url = "https://flux.api.airforce/"
- api_endpoint = "https://api.airforce/v1/imagine2"
- working = True
- default_model = 'flux-realism'
- models = [
- 'flux',
- 'flux-realism',
- 'flux-anime',
- 'flux-3d',
- 'flux-disney'
- ]
-
- @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",
- "origin": "https://flux.api.airforce",
- "priority": "u=1, i",
- "referer": "https://flux.api.airforce/",
- "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",
- "user-agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36"
- }
-
- prompt = messages[-1]['content'] if messages else ""
-
- params = {
- "prompt": prompt,
- "size": kwargs.get("size", "1:1"),
- "seed": kwargs.get("seed"),
- "model": model
- }
-
- 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(f"{cls.api_endpoint}", params=params, 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)
- 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)}"
-
- finally:
- if not session.closed:
- await session.close()
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/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 76c76a35..e6f70bed 100644
--- a/g4f/Provider/HuggingChat.py
+++ b/g4f/Provider/HuggingChat.py
@@ -12,26 +12,23 @@ class HuggingChat(AbstractProvider, ProviderModelMixin):
working = True
supports_stream = True
default_model = "meta-llama/Meta-Llama-3.1-70B-Instruct"
+
models = [
'meta-llama/Meta-Llama-3.1-70B-Instruct',
- 'meta-llama/Meta-Llama-3.1-405B-Instruct-FP8',
- 'CohereForAI/c4ai-command-r-plus',
- 'mistralai/Mixtral-8x7B-Instruct-v0.1',
- 'NousResearch/Nous-Hermes-2-Mixtral-8x7B-DPO',
- '01-ai/Yi-1.5-34B-Chat',
- 'mistralai/Mistral-7B-Instruct-v0.3',
- 'microsoft/Phi-3-mini-4k-instruct',
+ 'CohereForAI/c4ai-command-r-plus-08-2024',
+ 'Qwen/Qwen2.5-72B-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",
- "llama-3.1-405b": "meta-llama/Meta-Llama-3.1-405B-Instruct-FP8",
- "command-r-plus": "CohereForAI/c4ai-command-r-plus",
- "mixtral-8x7b": "mistralai/Mixtral-8x7B-Instruct-v0.1",
- "mixtral-8x7b": "NousResearch/Nous-Hermes-2-Mixtral-8x7B-DPO",
- "yi-1.5-34b": "01-ai/Yi-1.5-34B-Chat",
- "mistral-7b": "mistralai/Mistral-7B-Instruct-v0.3",
- "phi-3-mini-4k": "microsoft/Phi-3-mini-4k-instruct",
+ "command-r-plus": "CohereForAI/c4ai-command-r-plus-08-2024",
+ "qwen-2-72b": "Qwen/Qwen2.5-72B-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
@@ -80,7 +77,7 @@ class HuggingChat(AbstractProvider, ProviderModelMixin):
response = session.post('https://huggingface.co/chat/conversation', json=json_data)
conversationId = response.json()['conversationId']
- response = session.get(f'https://huggingface.co/chat/conversation/{conversationId}/__data.json?x-sveltekit-invalidated=01',)
+ response = session.get(f'https://huggingface.co/chat/conversation/{conversationId}/__data.json?x-sveltekit-invalidated=11',)
data: list = (response.json())["nodes"][1]["data"]
keys: list[int] = data[data[0]["messages"]]
diff --git a/g4f/Provider/HuggingFace.py b/g4f/Provider/HuggingFace.py
index 74957862..586e5f5f 100644
--- a/g4f/Provider/HuggingFace.py
+++ b/g4f/Provider/HuggingFace.py
@@ -9,33 +9,16 @@ from .helper import get_connector
from ..errors import RateLimitError, ModelNotFoundError
from ..requests.raise_for_status import raise_for_status
+from .HuggingChat import HuggingChat
+
class HuggingFace(AsyncGeneratorProvider, ProviderModelMixin):
url = "https://huggingface.co/chat"
working = True
needs_auth = True
supports_message_history = True
- default_model = "meta-llama/Meta-Llama-3.1-70B-Instruct"
- models = [
- 'meta-llama/Meta-Llama-3.1-70B-Instruct',
- 'meta-llama/Meta-Llama-3.1-405B-Instruct-FP8',
- 'CohereForAI/c4ai-command-r-plus',
- 'mistralai/Mixtral-8x7B-Instruct-v0.1',
- 'NousResearch/Nous-Hermes-2-Mixtral-8x7B-DPO',
- '01-ai/Yi-1.5-34B-Chat',
- 'mistralai/Mistral-7B-Instruct-v0.3',
- 'microsoft/Phi-3-mini-4k-instruct',
- ]
-
- model_aliases = {
- "llama-3.1-70b": "meta-llama/Meta-Llama-3.1-70B-Instruct",
- "llama-3.1-405b": "meta-llama/Meta-Llama-3.1-405B-Instruct-FP8",
- "command-r-plus": "CohereForAI/c4ai-command-r-plus",
- "mixtral-8x7b": "mistralai/Mixtral-8x7B-Instruct-v0.1",
- "mixtral-8x7b": "NousResearch/Nous-Hermes-2-Mixtral-8x7B-DPO",
- "yi-1.5-34b": "01-ai/Yi-1.5-34B-Chat",
- "mistral-7b": "mistralai/Mistral-7B-Instruct-v0.3",
- "phi-3-mini-4k": "microsoft/Phi-3-mini-4k-instruct",
- }
+ default_model = HuggingChat.default_model
+ models = HuggingChat.models
+ model_aliases = HuggingChat.model_aliases
@classmethod
def get_model(cls, model: str) -> str:
diff --git a/g4f/Provider/Koala.py b/g4f/Provider/Koala.py
index 0e810083..14e533df 100644
--- a/g4f/Provider/Koala.py
+++ b/g4f/Provider/Koala.py
@@ -10,7 +10,8 @@ from .helper import get_random_string, get_connector
from ..requests import raise_for_status
class Koala(AsyncGeneratorProvider, ProviderModelMixin):
- url = "https://koala.sh"
+ url = "https://koala.sh/chat"
+ api_endpoint = "https://koala.sh/api/gpt/"
working = True
supports_message_history = True
supports_gpt_4 = True
@@ -26,17 +27,17 @@ class Koala(AsyncGeneratorProvider, ProviderModelMixin):
**kwargs: Any
) -> AsyncGenerator[Dict[str, Union[str, int, float, List[Dict[str, Any]], None]], None]:
if not model:
- model = "gpt-3.5-turbo"
+ model = "gpt-4o-mini"
headers = {
"User-Agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:122.0) Gecko/20100101 Firefox/122.0",
"Accept": "text/event-stream",
"Accept-Language": "de,en-US;q=0.7,en;q=0.3",
"Accept-Encoding": "gzip, deflate, br",
- "Referer": f"{cls.url}/chat",
+ "Referer": f"{cls.url}",
"Flag-Real-Time-Data": "false",
"Visitor-ID": get_random_string(20),
- "Origin": cls.url,
+ "Origin": "https://koala.sh",
"Alt-Used": "koala.sh",
"Sec-Fetch-Dest": "empty",
"Sec-Fetch-Mode": "cors",
@@ -67,7 +68,7 @@ class Koala(AsyncGeneratorProvider, ProviderModelMixin):
"model": model,
}
- async with session.post(f"{cls.url}/api/gpt/", json=data, proxy=proxy) as response:
+ async with session.post(f"{cls.api_endpoint}", json=data, proxy=proxy) as response:
await raise_for_status(response)
async for chunk in cls._parse_event_stream(response):
yield chunk
diff --git a/g4f/Provider/Liaobots.py b/g4f/Provider/Liaobots.py
index 8a9f46b1..b292020e 100644
--- a/g4f/Provider/Liaobots.py
+++ b/g4f/Provider/Liaobots.py
@@ -36,32 +36,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 +99,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 +135,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 +144,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",
@@ -162,27 +162,27 @@ class Liaobots(AsyncGeneratorProvider, ProviderModelMixin):
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
index 69294a57..1b568e80 100644
--- a/g4f/Provider/LiteIcoding.py
+++ b/g4f/Provider/LiteIcoding.py
@@ -20,6 +20,25 @@ class LiteIcoding(AsyncGeneratorProvider, ProviderModelMixin):
'claude-3.5',
'gemini-1.5',
]
+
+ model_aliases = {
+ "gpt-4o-mini": "gpt-4o",
+ "gemini-pro": "gemini-1.5",
+ }
+
+ bearer_tokens = [
+ "aa3020ee873e40cb8b3f515a0708ebc4",
+ "5d69cd271b144226ac1199b3c849a566",
+ "62977f48a95844f8853a953679401850",
+ "d815b091959e42dd8b7871dfaf879485"
+ ]
+ current_token_index = 0
+
+ @classmethod
+ def get_next_bearer_token(cls):
+ token = cls.bearer_tokens[cls.current_token_index]
+ cls.current_token_index = (cls.current_token_index + 1) % len(cls.bearer_tokens)
+ return token
@classmethod
async def create_async_generator(
@@ -29,10 +48,11 @@ class LiteIcoding(AsyncGeneratorProvider, ProviderModelMixin):
proxy: str = None,
**kwargs
) -> AsyncResult:
+ bearer_token = cls.get_next_bearer_token()
headers = {
"Accept": "*/*",
"Accept-Language": "en-US,en;q=0.9",
- "Authorization": "Bearer aa3020ee873e40cb8b3f515a0708ebc4",
+ "Authorization": f"Bearer {bearer_token}",
"Connection": "keep-alive",
"Content-Type": "application/json;charset=utf-8",
"DNT": "1",
@@ -87,20 +107,17 @@ class LiteIcoding(AsyncGeneratorProvider, ProviderModelMixin):
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
+ full_response.replace('""', '')
+ .replace('" "', ' ')
.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
diff --git a/g4f/Provider/Llama.py b/g4f/Provider/Llama.py
deleted file mode 100644
index 235c0994..00000000
--- a/g4f/Provider/Llama.py
+++ /dev/null
@@ -1,91 +0,0 @@
-from __future__ import annotations
-
-from aiohttp import ClientSession
-
-from ..typing import AsyncResult, Messages
-from ..requests.raise_for_status import raise_for_status
-from .base_provider import AsyncGeneratorProvider, ProviderModelMixin
-
-
-class Llama(AsyncGeneratorProvider, ProviderModelMixin):
- url = "https://www.llama2.ai"
- working = False
- supports_message_history = True
- default_model = "meta/meta-llama-3-70b-instruct"
- models = [
- "meta/llama-2-7b-chat",
- "meta/llama-2-13b-chat",
- "meta/llama-2-70b-chat",
- "meta/meta-llama-3-8b-instruct",
- "meta/meta-llama-3-70b-instruct",
- ]
- model_aliases = {
- "meta-llama/Meta-Llama-3-8B-Instruct": "meta/meta-llama-3-8b-instruct",
- "meta-llama/Meta-Llama-3-70B-Instruct": "meta/meta-llama-3-70b-instruct",
- "meta-llama/Llama-2-7b-chat-hf": "meta/llama-2-7b-chat",
- "meta-llama/Llama-2-13b-chat-hf": "meta/llama-2-13b-chat",
- "meta-llama/Llama-2-70b-chat-hf": "meta/llama-2-70b-chat",
- }
-
- @classmethod
- async def create_async_generator(
- cls,
- model: str,
- messages: Messages,
- proxy: str = None,
- system_message: str = "You are a helpful assistant.",
- temperature: float = 0.75,
- top_p: float = 0.9,
- max_tokens: int = 8000,
- **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",
- "Referer": f"{cls.url}/",
- "Content-Type": "text/plain;charset=UTF-8",
- "Origin": cls.url,
- "Connection": "keep-alive",
- "Sec-Fetch-Dest": "empty",
- "Sec-Fetch-Mode": "cors",
- "Sec-Fetch-Site": "same-origin",
- "Pragma": "no-cache",
- "Cache-Control": "no-cache",
- "TE": "trailers"
- }
- async with ClientSession(headers=headers) as session:
- system_messages = [message["content"] for message in messages if message["role"] == "system"]
- if system_messages:
- system_message = "\n".join(system_messages)
- messages = [message for message in messages if message["role"] != "system"]
- prompt = format_prompt(messages)
- data = {
- "prompt": prompt,
- "model": cls.get_model(model),
- "systemPrompt": system_message,
- "temperature": temperature,
- "topP": top_p,
- "maxTokens": max_tokens,
- "image": None
- }
- started = False
- async with session.post(f"{cls.url}/api", json=data, proxy=proxy) as response:
- await raise_for_status(response)
- async for chunk in response.content.iter_any():
- if not chunk:
- continue
- if not started:
- chunk = chunk.lstrip()
- started = True
- yield chunk.decode(errors="ignore")
-
-def format_prompt(messages: Messages):
- messages = [
- f"[INST] {message['content']} [/INST]"
- if message["role"] == "user"
- else message["content"]
- for message in messages
- ]
- return "\n".join(messages) + "\n"
diff --git a/g4f/Provider/MagickPen.py b/g4f/Provider/MagickPen.py
index eab70536..b6a47417 100644
--- a/g4f/Provider/MagickPen.py
+++ b/g4f/Provider/MagickPen.py
@@ -1,72 +1,57 @@
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/9e47cd7579e60a9d1f13.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()
+
+ # Extract the necessary values from the file
+ pattern = r'"X-API-Secret":"(\w+)"'
+ match = re.search(pattern, text)
+ X_API_SECRET = match.group(1) if match else None
+
+ # Generate timestamp and nonce
+ timestamp = str(int(time.time() * 1000)) # in milliseconds
+ nonce = str(random.random())
+
+ # Generate the signature
+ 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 +62,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
index e2c3e197..33e794f6 100644
--- a/g4f/Provider/Nexra.py
+++ b/g4f/Provider/Nexra.py
@@ -1,40 +1,49 @@
from __future__ import annotations
-import json
-import base64
from aiohttp import ClientSession
-from typing import AsyncGenerator
-
-from ..typing import AsyncResult, Messages
from .base_provider import AsyncGeneratorProvider, ProviderModelMixin
-from ..image import ImageResponse
from .helper import format_prompt
+from .nexra.NexraBing import NexraBing
+from .nexra.NexraChatGPT import NexraChatGPT
+from .nexra.NexraChatGPT4o import NexraChatGPT4o
+from .nexra.NexraChatGPTWeb import NexraChatGPTWeb
+from .nexra.NexraGeminiPro import NexraGeminiPro
+from .nexra.NexraImageURL import NexraImageURL
+from .nexra.NexraLlama import NexraLlama
+from .nexra.NexraQwen import NexraQwen
class Nexra(AsyncGeneratorProvider, ProviderModelMixin):
url = "https://nexra.aryahcr.cc"
- api_endpoint_text = "https://nexra.aryahcr.cc/api/chat/gpt"
- api_endpoint_image = "https://nexra.aryahcr.cc/api/image/complements"
working = True
supports_gpt_35_turbo = True
supports_gpt_4 = True
supports_stream = True
supports_system_message = True
supports_message_history = True
-
default_model = 'gpt-3.5-turbo'
- models = [
- # 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', 'dalle-mini', 'emi'
- ]
+ image_model = 'sdxl-turbo'
- image_models = {"dalle", "dalle-mini", "emi"}
- text_models = set(models) - image_models
+ models = (
+ *NexraBing.models,
+ *NexraChatGPT.models,
+ *NexraChatGPT4o.models,
+ *NexraChatGPTWeb.models,
+ *NexraGeminiPro.models,
+ *NexraImageURL.models,
+ *NexraLlama.models,
+ *NexraQwen.models,
+ )
+
+ model_to_provider = {
+ **{model: NexraChatGPT for model in NexraChatGPT.models},
+ **{model: NexraChatGPT4o for model in NexraChatGPT4o.models},
+ **{model: NexraChatGPTWeb for model in NexraChatGPTWeb.models},
+ **{model: NexraGeminiPro for model in NexraGeminiPro.models},
+ **{model: NexraImageURL for model in NexraImageURL.models},
+ **{model: NexraLlama for model in NexraLlama.models},
+ **{model: NexraQwen for model in NexraQwen.models},
+ **{model: NexraBing for model in NexraBing.models},
+ }
model_aliases = {
"gpt-4": "gpt-4-0613",
@@ -60,8 +69,18 @@ class Nexra(AsyncGeneratorProvider, ProviderModelMixin):
"gpt-3": "ada",
"gpt-3": "babbage-002",
"gpt-3": "davinci-002",
+
+ "gpt-4": "gptweb",
+
+ "gpt-4": "Bing (Balanced)",
+ "gpt-4": "Bing (Creative)",
+ "gpt-4": "Bing (Precise)",
+
+ "dalle-2": "dalle2",
+ "sdxl": "sdxl-turbo",
}
+
@classmethod
def get_model(cls, model: str) -> str:
if model in cls.models:
@@ -72,110 +91,28 @@ class Nexra(AsyncGeneratorProvider, ProviderModelMixin):
return cls.default_model
@classmethod
- async def create_async_generator(
- cls,
- model: str,
- messages: Messages,
- proxy: str = None,
- **kwargs
- ) -> AsyncGenerator[str | ImageResponse, None]:
- model = cls.get_model(model)
-
- if model in cls.image_models:
- async for result in cls.create_image_async_generator(model, messages, proxy, **kwargs):
- yield result
- else:
- async for result in cls.create_text_async_generator(model, messages, proxy, **kwargs):
- yield result
+ def get_api_endpoint(cls, model: str) -> str:
+ provider_class = cls.model_to_provider.get(model)
- @classmethod
- async def create_text_async_generator(
- cls,
- model: str,
- messages: Messages,
- proxy: str = None,
- **kwargs
- ) -> AsyncGenerator[str, None]:
- headers = {
- "Content-Type": "application/json",
- }
- async with ClientSession(headers=headers) as session:
- data = {
- "messages": messages,
- "prompt": format_prompt(messages),
- "model": model,
- "markdown": False,
- "stream": False,
- }
- async with session.post(cls.api_endpoint_text, json=data, proxy=proxy) as response:
- response.raise_for_status()
- result = await response.text()
- json_result = json.loads(result)
- yield json_result["gpt"]
+ if provider_class:
+ return provider_class.api_endpoint
+ raise ValueError(f"API endpoint for model {model} not found.")
@classmethod
- async def create_image_async_generator(
+ async def create_async_generator(
cls,
model: str,
messages: Messages,
proxy: str = None,
**kwargs
- ) -> AsyncGenerator[ImageResponse | str, None]:
- headers = {
- "Content-Type": "application/json"
- }
-
- prompt = messages[-1]['content'] if messages else ""
-
- data = {
- "prompt": prompt,
- "model": model
- }
-
- async def process_response(response_text: str) -> ImageResponse | None:
- json_start = response_text.find('{')
- if json_start != -1:
- json_data = response_text[json_start:]
- try:
- response_data = json.loads(json_data)
- image_data = response_data.get('images', [])[0]
-
- if image_data.startswith('data:image/'):
- return ImageResponse([image_data], "Generated image")
-
- try:
- base64.b64decode(image_data)
- data_uri = f"data:image/jpeg;base64,{image_data}"
- return ImageResponse([data_uri], "Generated image")
- except:
- print("Invalid base64 data")
- return None
- except json.JSONDecodeError:
- print("Failed to parse JSON.")
- else:
- print("No JSON data found in the response.")
- return None
+ ) -> AsyncResult:
+ model = cls.get_model(model)
+ api_endpoint = cls.get_api_endpoint(model)
- async with ClientSession(headers=headers) as session:
- async with session.post(cls.api_endpoint_image, json=data, proxy=proxy) as response:
- response.raise_for_status()
- response_text = await response.text()
-
- image_response = await process_response(response_text)
- if image_response:
- yield image_response
- else:
- yield "Failed to process image data."
+ provider_class = cls.model_to_provider.get(model)
- @classmethod
- async def create_async(
- cls,
- model: str,
- messages: Messages,
- proxy: str = None,
- **kwargs
- ) -> str:
- async for response in cls.create_async_generator(model, messages, proxy, **kwargs):
- if isinstance(response, ImageResponse):
- return response.images[0]
- return response
+ if provider_class:
+ async for response in provider_class.create_async_generator(model, messages, proxy, **kwargs):
+ yield response
+ else:
+ raise ValueError(f"Provider for model {model} not found.")
diff --git a/g4f/Provider/PerplexityLabs.py b/g4f/Provider/PerplexityLabs.py
index 3656a39b..b776e96a 100644
--- a/g4f/Provider/PerplexityLabs.py
+++ b/g4f/Provider/PerplexityLabs.py
@@ -13,7 +13,7 @@ WS_URL = "wss://www.perplexity.ai/socket.io/"
class PerplexityLabs(AsyncGeneratorProvider, ProviderModelMixin):
url = "https://labs.perplexity.ai"
working = True
- default_model = "llama-3.1-8b-instruct"
+ default_model = "llama-3.1-70b-instruct"
models = [
"llama-3.1-sonar-large-128k-online",
"llama-3.1-sonar-small-128k-online",
@@ -22,6 +22,15 @@ class PerplexityLabs(AsyncGeneratorProvider, ProviderModelMixin):
"llama-3.1-8b-instruct",
"llama-3.1-70b-instruct",
]
+
+ model_aliases = {
+ "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",
+ }
@classmethod
async def create_async_generator(
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/Prodia.py b/g4f/Provider/Prodia.py
new file mode 100644
index 00000000..dd87a34c
--- /dev/null
+++ b/g4f/Provider/Prodia.py
@@ -0,0 +1,149 @@
+from __future__ import annotations
+
+from aiohttp import ClientSession
+import time
+import asyncio
+
+from ..typing import AsyncResult, Messages
+from .base_provider import AsyncGeneratorProvider, ProviderModelMixin
+from ..image import ImageResponse
+
+class Prodia(AsyncGeneratorProvider, ProviderModelMixin):
+ url = "https://app.prodia.com"
+ api_endpoint = "https://api.prodia.com/generate"
+ working = True
+
+ default_model = 'absolutereality_v181.safetensors [3d9d4d2b]'
+ models = [
+ '3Guofeng3_v34.safetensors [50f420de]',
+ 'absolutereality_V16.safetensors [37db0fc3]',
+ 'absolutereality_v181.safetensors [3d9d4d2b]',
+ '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]',
+ ]
+
+ @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",
+ "origin": cls.url,
+ "referer": f"{cls.url}/",
+ "user-agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36"
+ }
+
+ async with ClientSession(headers=headers) as session:
+ prompt = messages[-1]['content'] if messages else ""
+
+ params = {
+ "new": "true",
+ "prompt": prompt,
+ "model": model,
+ "negative_prompt": kwargs.get("negative_prompt", ""),
+ "steps": kwargs.get("steps", 20),
+ "cfg": kwargs.get("cfg", 7),
+ "seed": kwargs.get("seed", int(time.time())),
+ "sampler": kwargs.get("sampler", "DPM++ 2M Karras"),
+ "aspect_ratio": kwargs.get("aspect_ratio", "square")
+ }
+
+ async with session.get(cls.api_endpoint, params=params, proxy=proxy) as response:
+ response.raise_for_status()
+ job_data = await response.json()
+ job_id = job_data["job"]
+
+ image_url = await cls._poll_job(session, job_id, proxy)
+ yield ImageResponse(image_url, alt=prompt)
+
+ @classmethod
+ async def _poll_job(cls, session: ClientSession, job_id: str, proxy: str, max_attempts: int = 30, delay: int = 2) -> str:
+ for _ in range(max_attempts):
+ async with session.get(f"https://api.prodia.com/job/{job_id}", proxy=proxy) as response:
+ response.raise_for_status()
+ job_status = await response.json()
+
+ if job_status["status"] == "succeeded":
+ return f"https://images.prodia.xyz/{job_id}.png"
+ elif job_status["status"] == "failed":
+ raise Exception("Image generation failed")
+
+ await asyncio.sleep(delay)
+
+ raise Exception("Timeout waiting for image generation")
diff --git a/g4f/Provider/ReplicateHome.py b/g4f/Provider/ReplicateHome.py
index c4e52ad6..7f443a7d 100644
--- a/g4f/Provider/ReplicateHome.py
+++ b/g4f/Provider/ReplicateHome.py
@@ -1,66 +1,60 @@
from __future__ import annotations
-from typing import Generator, Optional, Dict, Any, Union, List
-import random
+
+import json
import asyncio
-import base64
+from aiohttp import ClientSession, ContentTypeError
-from .base_provider import AsyncGeneratorProvider, ProviderModelMixin
from ..typing import AsyncResult, Messages
-from ..requests import StreamSession, raise_for_status
-from ..errors import ResponseError
+from .base_provider import AsyncGeneratorProvider, ProviderModelMixin
+from .helper import format_prompt
from ..image import ImageResponse
class ReplicateHome(AsyncGeneratorProvider, ProviderModelMixin):
url = "https://replicate.com"
- parent = "Replicate"
+ api_endpoint = "https://homepage.replicate.com/api/prediction"
working = True
+ supports_stream = True
+ supports_system_message = True
+ supports_message_history = True
+
default_model = 'meta/meta-llama-3-70b-instruct'
- models = [
- # Models for image generation
- 'stability-ai/stable-diffusion-3',
- 'bytedance/sdxl-lightning-4step',
- 'playgroundai/playground-v2.5-1024px-aesthetic',
-
- # Models for image generation
+
+ text_models = [
'meta/meta-llama-3-70b-instruct',
'mistralai/mixtral-8x7b-instruct-v0.1',
'google-deepmind/gemma-2b-it',
+ 'yorickvp/llava-13b',
]
- versions = {
- # Model versions for generating images
- 'stability-ai/stable-diffusion-3': [
- "527d2a6296facb8e47ba1eaf17f142c240c19a30894f437feee9b91cc29d8e4f"
- ],
- 'bytedance/sdxl-lightning-4step': [
- "5f24084160c9089501c1b3545d9be3c27883ae2239b6f412990e82d4a6210f8f"
- ],
- 'playgroundai/playground-v2.5-1024px-aesthetic': [
- "a45f82a1382bed5c7aeb861dac7c7d191b0fdf74d8d57c4a0e6ed7d4d0bf7d24"
- ],
-
- # Model versions for text generation
- 'meta/meta-llama-3-70b-instruct': [
- "dp-cf04fe09351e25db628e8b6181276547"
- ],
- 'mistralai/mixtral-8x7b-instruct-v0.1': [
- "dp-89e00f489d498885048e94f9809fbc76"
- ],
- 'google-deepmind/gemma-2b-it': [
- "dff94eaf770e1fc211e425a50b51baa8e4cac6c39ef074681f9e39d778773626"
- ]
- }
-
- image_models = {"stability-ai/stable-diffusion-3", "bytedance/sdxl-lightning-4step", "playgroundai/playground-v2.5-1024px-aesthetic"}
- text_models = {"meta/meta-llama-3-70b-instruct", "mistralai/mixtral-8x7b-instruct-v0.1", "google-deepmind/gemma-2b-it"}
+ image_models = [
+ 'black-forest-labs/flux-schnell',
+ 'stability-ai/stable-diffusion-3',
+ 'bytedance/sdxl-lightning-4step',
+ 'playgroundai/playground-v2.5-1024px-aesthetic',
+ ]
+ models = text_models + image_models
+
model_aliases = {
+ "flux-schnell": "black-forest-labs/flux-schnell",
"sd-3": "stability-ai/stable-diffusion-3",
"sdxl": "bytedance/sdxl-lightning-4step",
"playground-v2.5": "playgroundai/playground-v2.5-1024px-aesthetic",
"llama-3-70b": "meta/meta-llama-3-70b-instruct",
"mixtral-8x7b": "mistralai/mixtral-8x7b-instruct-v0.1",
"gemma-2b": "google-deepmind/gemma-2b-it",
+ "llava-13b": "yorickvp/llava-13b",
+ }
+
+ model_versions = {
+ "meta/meta-llama-3-70b-instruct": "fbfb20b472b2f3bdd101412a9f70a0ed4fc0ced78a77ff00970ee7a2383c575d",
+ "mistralai/mixtral-8x7b-instruct-v0.1": "5d78bcd7a992c4b793465bcdcf551dc2ab9668d12bb7aa714557a21c1e77041c",
+ "google-deepmind/gemma-2b-it": "dff94eaf770e1fc211e425a50b51baa8e4cac6c39ef074681f9e39d778773626",
+ "yorickvp/llava-13b": "80537f9eead1a5bfa72d5ac6ea6414379be41d4d4f6679fd776e9535d1eb58bb",
+ 'black-forest-labs/flux-schnell': "f2ab8a5bfe79f02f0789a146cf5e73d2a4ff2684a98c2b303d1e1ff3814271db",
+ 'stability-ai/stable-diffusion-3': "527d2a6296facb8e47ba1eaf17f142c240c19a30894f437feee9b91cc29d8e4f",
+ 'bytedance/sdxl-lightning-4step': "5f24084160c9089501c1b3545d9be3c27883ae2239b6f412990e82d4a6210f8f",
+ 'playgroundai/playground-v2.5-1024px-aesthetic': "a45f82a1382bed5c7aeb861dac7c7d191b0fdf74d8d57c4a0e6ed7d4d0bf7d24",
}
@classmethod
@@ -77,84 +71,73 @@ class ReplicateHome(AsyncGeneratorProvider, ProviderModelMixin):
cls,
model: str,
messages: Messages,
- **kwargs: Any
- ) -> Generator[Union[str, ImageResponse], None, None]:
- yield await cls.create_async(messages[-1]["content"], model, **kwargs)
-
- @classmethod
- async def create_async(
- cls,
- prompt: str,
- model: str,
- api_key: Optional[str] = None,
- proxy: Optional[str] = None,
- timeout: int = 180,
- version: Optional[str] = None,
- extra_data: Dict[str, Any] = {},
- **kwargs: Any
- ) -> Union[str, ImageResponse]:
- model = cls.get_model(model) # Use the get_model method to resolve model name
+ proxy: str = None,
+ **kwargs
+ ) -> AsyncResult:
+ model = cls.get_model(model)
+
headers = {
- 'Accept-Encoding': 'gzip, deflate, br',
- 'Accept-Language': 'en-US',
- 'Connection': 'keep-alive',
- 'Origin': cls.url,
- 'Referer': f'{cls.url}/',
- 'Sec-Fetch-Dest': 'empty',
- 'Sec-Fetch-Mode': 'cors',
- 'Sec-Fetch-Site': 'same-site',
- 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36',
- 'sec-ch-ua': '"Google Chrome";v="119", "Chromium";v="119", "Not?A_Brand";v="24"',
- 'sec-ch-ua-mobile': '?0',
- 'sec-ch-ua-platform': '"macOS"',
+ "accept": "*/*",
+ "accept-language": "en-US,en;q=0.9",
+ "cache-control": "no-cache",
+ "content-type": "application/json",
+ "origin": "https://replicate.com",
+ "pragma": "no-cache",
+ "priority": "u=1, i",
+ "referer": "https://replicate.com/",
+ "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-site",
+ "user-agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36"
}
-
- if version is None:
- version = random.choice(cls.versions.get(model, []))
- if api_key is not None:
- headers["Authorization"] = f"Bearer {api_key}"
-
- async with StreamSession(
- proxies={"all": proxy},
- headers=headers,
- timeout=timeout
- ) as session:
+
+ async with ClientSession(headers=headers) as session:
+ if model in cls.image_models:
+ prompt = messages[-1]['content'] if messages else ""
+ else:
+ prompt = format_prompt(messages)
+
data = {
- "input": {
- "prompt": prompt,
- **extra_data
- },
- "version": version
+ "model": model,
+ "version": cls.model_versions[model],
+ "input": {"prompt": prompt},
}
- if api_key is None:
- data["model"] = model
- url = "https://homepage.replicate.com/api/prediction"
- else:
- url = "https://api.replicate.com/v1/predictions"
- async with session.post(url, json=data) as response:
- await raise_for_status(response)
+
+ async with session.post(cls.api_endpoint, json=data, proxy=proxy) as response:
+ response.raise_for_status()
result = await response.json()
- if "id" not in result:
- raise ResponseError(f"Invalid response: {result}")
+ prediction_id = result['id']
+
+ poll_url = f"https://homepage.replicate.com/api/poll?id={prediction_id}"
+ max_attempts = 30
+ delay = 5
+ for _ in range(max_attempts):
+ async with session.get(poll_url, proxy=proxy) as response:
+ response.raise_for_status()
+ try:
+ result = await response.json()
+ except ContentTypeError:
+ text = await response.text()
+ try:
+ result = json.loads(text)
+ except json.JSONDecodeError:
+ raise ValueError(f"Unexpected response format: {text}")
- while True:
- if api_key is None:
- url = f"https://homepage.replicate.com/api/poll?id={result['id']}"
- else:
- url = f"https://api.replicate.com/v1/predictions/{result['id']}"
- async with session.get(url) as response:
- await raise_for_status(response)
- result = await response.json()
- if "status" not in result:
- raise ResponseError(f"Invalid response: {result}")
- if result["status"] == "succeeded":
- output = result['output']
- if model in cls.text_models:
- return ''.join(output) if isinstance(output, list) else output
- elif model in cls.image_models:
- images: List[Any] = output
- images = images[0] if len(images) == 1 else images
- return ImageResponse(images, prompt)
- elif result["status"] == "failed":
- raise ResponseError(f"Prediction failed: {result}")
- await asyncio.sleep(0.5)
+ if result['status'] == 'succeeded':
+ if model in cls.image_models:
+ image_url = result['output'][0]
+ yield ImageResponse(image_url, "Generated image")
+ return
+ else:
+ for chunk in result['output']:
+ yield chunk
+ break
+ elif result['status'] == 'failed':
+ raise Exception(f"Prediction failed: {result.get('error')}")
+ await asyncio.sleep(delay)
+
+ if result['status'] != 'succeeded':
+ raise Exception("Prediction timed out")
diff --git a/g4f/Provider/Rocks.py b/g4f/Provider/Rocks.py
deleted file mode 100644
index f44e0060..00000000
--- a/g4f/Provider/Rocks.py
+++ /dev/null
@@ -1,70 +0,0 @@
-import asyncio
-import json
-from aiohttp import ClientSession
-from ..typing import Messages, AsyncResult
-from .base_provider import AsyncGeneratorProvider
-
-class Rocks(AsyncGeneratorProvider):
- url = "https://api.airforce"
- api_endpoint = "/chat/completions"
- supports_message_history = True
- supports_gpt_35_turbo = True
- supports_gpt_4 = True
- supports_stream = True
- supports_system_message = True
- working = True
-
- @classmethod
- async def create_async_generator(
- cls,
- model: str,
- messages: Messages,
- proxy: str = None,
- **kwargs
- ) -> AsyncResult:
- payload = {"messages":messages,"model":model,"max_tokens":4096,"temperature":1,"top_p":1,"stream":True}
-
- headers = {
- "Accept": "application/json",
- "Accept-Encoding": "gzip, deflate, br, zstd",
- "Accept-Language": "en-US,en;q=0.9",
- "Authorization": "Bearer missing api key",
- "Origin": "https://llmplayground.net",
- "Referer": "https://llmplayground.net/",
- "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/127.0.0.0 Safari/537.36",
- }
-
- async with ClientSession() as session:
- async with session.post(
- f"{cls.url}{cls.api_endpoint}",
- json=payload,
- proxy=proxy,
- headers=headers
- ) as response:
- response.raise_for_status()
- last_chunk_time = asyncio.get_event_loop().time()
-
- async for line in response.content:
- current_time = asyncio.get_event_loop().time()
- if current_time - last_chunk_time > 5:
- return
-
- if line.startswith(b"\n"):
- pass
- elif "discord.com/invite/" in line.decode() or "discord.gg/" in line.decode():
- pass # trolled
- elif line.startswith(b"data: "):
- try:
- line = json.loads(line[6:])
- except json.JSONDecodeError:
- continue
- chunk = line["choices"][0]["delta"].get("content")
- if chunk:
- yield chunk
- last_chunk_time = current_time
- else:
- raise Exception(f"Unexpected line: {line}")
- return \ No newline at end of file
diff --git a/g4f/Provider/Snova.py b/g4f/Provider/Snova.py
deleted file mode 100644
index 76dfac40..00000000
--- a/g4f/Provider/Snova.py
+++ /dev/null
@@ -1,133 +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',
- 'v1olet/v1olet_merged_dpo_7B',
- 'macadeliccc/WestLake-7B-v2-laser-truthy-dpo',
- 'cookinai/DonutLM-v1',
- ]
-
- 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",
- "donutlm-v1": "cookinai/DonutLM-v1",
- }
-
- @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..85d3a63e 100644
--- a/g4f/Provider/Upstage.py
+++ b/g4f/Provider/Upstage.py
@@ -12,10 +12,11 @@ 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",
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/__init__.py b/g4f/Provider/__init__.py
index a9a815ea..82cb9ff2 100644
--- a/g4f/Provider/__init__.py
+++ b/g4f/Provider/__init__.py
@@ -10,9 +10,11 @@ from .selenium import *
from .needs_auth import *
from .AI365VIP import AI365VIP
+from .AIChatFree import AIChatFree
from .Allyfy import Allyfy
from .AiChatOnline import AiChatOnline
from .AiChats import AiChats
+from .Airforce import Airforce
from .Aura import Aura
from .Bing import Bing
from .BingCreateImages import BingCreateImages
@@ -20,46 +22,44 @@ 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 .DDG import DDG
from .DeepInfra import DeepInfra
+from .DeepInfraChat import DeepInfraChat
from .DeepInfraImage import DeepInfraImage
from .FlowGpt import FlowGpt
-from .FluxAirforce import FluxAirforce
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 .GPROChat import GPROChat
from .HuggingChat import HuggingChat
from .HuggingFace import HuggingFace
from .Koala import Koala
from .Liaobots import Liaobots
from .LiteIcoding import LiteIcoding
-from .Llama import Llama
from .Local import Local
from .MagickPen import MagickPen
from .MetaAI import MetaAI
-from .MetaAIAccount import MetaAIAccount
+#from .MetaAIAccount import MetaAIAccount
from .Nexra import Nexra
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 .Rocks import Rocks
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/bing/conversation.py b/g4f/Provider/bing/conversation.py
index a4195fa4..b5c237f9 100644
--- a/g4f/Provider/bing/conversation.py
+++ b/g4f/Provider/bing/conversation.py
@@ -33,9 +33,9 @@ async def create_conversation(session: StreamSession, headers: dict, tone: str)
Conversation: An instance representing the created conversation.
"""
if tone == "Copilot":
- url = "https://copilot.microsoft.com/turing/conversation/create?bundleVersion=1.1690.0"
+ url = "https://copilot.microsoft.com/turing/conversation/create?bundleVersion=1.1809.0"
else:
- url = "https://www.bing.com/turing/conversation/create?bundleVersion=1.1690.0"
+ url = "https://www.bing.com/turing/conversation/create?bundleVersion=1.1809.0"
async with session.get(url, headers=headers) as response:
if response.status == 404:
raise RateLimitError("Response 404: Do less requests and reuse conversations")
@@ -90,4 +90,4 @@ async def delete_conversation(session: StreamSession, conversation: Conversation
response = await response.json()
return response["result"]["value"] == "Success"
except:
- return False \ No newline at end of file
+ return False
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/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..59e06a3d
--- /dev/null
+++ b/g4f/Provider/nexra/NexraBing.py
@@ -0,0 +1,82 @@
+from __future__ import annotations
+from aiohttp import ClientSession
+from ...typing import AsyncResult, Messages
+from ..base_provider import AsyncGeneratorProvider, ProviderModelMixin
+from ..helper import format_prompt
+import json
+
+class NexraBing(AsyncGeneratorProvider, ProviderModelMixin):
+ label = "Nexra Bing"
+ api_endpoint = "https://nexra.aryahcr.cc/api/chat/complements"
+
+ bing_models = {
+ 'Bing (Balanced)': 'Balanced',
+ 'Bing (Creative)': 'Creative',
+ 'Bing (Precise)': 'Precise'
+ }
+
+ models = [*bing_models.keys()]
+
+ @classmethod
+ async def create_async_generator(
+ cls,
+ model: str,
+ messages: Messages,
+ proxy: str = None,
+ **kwargs
+ ) -> AsyncResult:
+ headers = {
+ "Content-Type": "application/json",
+ "Accept": "application/json",
+ "Origin": cls.url or "https://default-url.com",
+ "Referer": f"{cls.url}/chat" if cls.url else "https://default-url.com/chat",
+ }
+
+ async with ClientSession(headers=headers) as session:
+ prompt = format_prompt(messages)
+ if prompt is None:
+ raise ValueError("Prompt cannot be None")
+
+ data = {
+ "messages": [
+ {
+ "role": "user",
+ "content": prompt
+ }
+ ],
+ "conversation_style": cls.bing_models.get(model, 'Balanced'),
+ "markdown": False,
+ "stream": True,
+ "model": "Bing"
+ }
+
+ full_response = ""
+ last_message = ""
+
+ async with session.post(cls.api_endpoint, json=data, proxy=proxy) as response:
+ response.raise_for_status()
+
+ async for line in response.content:
+ if line:
+ raw_data = line.decode('utf-8').strip()
+
+ parts = raw_data.split('')
+ for part in parts:
+ if part:
+ try:
+ json_data = json.loads(part)
+ except json.JSONDecodeError:
+ continue
+
+ if json_data.get("error"):
+ raise Exception("Error in API response")
+
+ if json_data.get("finish"):
+ break
+
+ if message := json_data.get("message"):
+ if message != last_message:
+ full_response = message
+ last_message = message
+
+ yield full_response.strip()
diff --git a/g4f/Provider/nexra/NexraChatGPT.py b/g4f/Provider/nexra/NexraChatGPT.py
new file mode 100644
index 00000000..8ed83f98
--- /dev/null
+++ b/g4f/Provider/nexra/NexraChatGPT.py
@@ -0,0 +1,66 @@
+from __future__ import annotations
+from aiohttp import ClientSession
+from ...typing import AsyncResult, Messages
+from ..base_provider import AsyncGeneratorProvider, ProviderModelMixin
+from ..helper import format_prompt
+import json
+
+class NexraChatGPT(AsyncGeneratorProvider, ProviderModelMixin):
+ label = "Nexra ChatGPT"
+ api_endpoint = "https://nexra.aryahcr.cc/api/chat/gpt"
+
+ models = [
+ 'gpt-4', 'gpt-4-0613', 'gpt-4-32k', 'gpt-4-0314', 'gpt-4-32k-0314',
+ 'gpt-3.5-turbo', 'gpt-3.5-turbo-16k', 'gpt-3.5-turbo-0613',
+ 'gpt-3.5-turbo-16k-0613', 'gpt-3.5-turbo-0301',
+ 'gpt-3', 'text-davinci-003', 'text-davinci-002', 'code-davinci-002',
+ 'text-curie-001', 'text-babbage-001', 'text-ada-001',
+ 'davinci', 'curie', 'babbage', 'ada', 'babbage-002', 'davinci-002',
+ ]
+
+ @classmethod
+ async def create_async_generator(
+ cls,
+ model: str,
+ messages: Messages,
+ proxy: str = None,
+ **kwargs
+ ) -> AsyncResult:
+ headers = {
+ "Accept": "application/json",
+ "Content-Type": "application/json",
+ "Referer": f"{cls.url}/chat",
+ }
+
+ async with ClientSession(headers=headers) as session:
+ prompt = format_prompt(messages)
+ data = {
+ "prompt": prompt,
+ "model": model,
+ "markdown": False,
+ "messages": messages or [],
+ }
+
+ async with session.post(cls.api_endpoint, json=data, proxy=proxy) as response:
+ response.raise_for_status()
+
+ content_type = response.headers.get('Content-Type', '')
+ if 'application/json' in content_type:
+ result = await response.json()
+ if result.get("status"):
+ yield result.get("gpt", "")
+ else:
+ raise Exception(f"Error in response: {result.get('message', 'Unknown error')}")
+ elif 'text/plain' in content_type:
+ text = await response.text()
+ try:
+ result = json.loads(text)
+ if result.get("status"):
+ yield result.get("gpt", "")
+ else:
+ raise Exception(f"Error in response: {result.get('message', 'Unknown error')}")
+ except json.JSONDecodeError:
+ yield text # If not JSON, return text
+ else:
+ raise Exception(f"Unexpected response type: {content_type}. Response text: {await response.text()}")
+
diff --git a/g4f/Provider/nexra/NexraChatGPT4o.py b/g4f/Provider/nexra/NexraChatGPT4o.py
new file mode 100644
index 00000000..eb18d439
--- /dev/null
+++ b/g4f/Provider/nexra/NexraChatGPT4o.py
@@ -0,0 +1,52 @@
+from __future__ import annotations
+
+import json
+from aiohttp import ClientSession
+
+from ...typing import AsyncResult, Messages
+from ..base_provider import AsyncGeneratorProvider, ProviderModelMixin
+from ..helper import format_prompt
+
+
+class NexraChatGPT4o(AsyncGeneratorProvider, ProviderModelMixin):
+ label = "Nexra GPT-4o"
+ api_endpoint = "https://nexra.aryahcr.cc/api/chat/complements"
+ models = ['gpt-4o']
+
+ @classmethod
+ async def create_async_generator(
+ cls,
+ model: str,
+ messages: Messages,
+ proxy: str = None,
+ **kwargs
+ ) -> AsyncResult:
+ headers = {
+ "Content-Type": "application/json"
+ }
+ async with ClientSession(headers=headers) as session:
+ data = {
+ "messages": [
+ {'role': 'assistant', 'content': ''},
+ {'role': 'user', 'content': format_prompt(messages)}
+ ],
+ "markdown": False,
+ "stream": True,
+ "model": model
+ }
+ async with session.post(cls.api_endpoint, json=data, proxy=proxy) as response:
+ response.raise_for_status()
+ full_response = ''
+ async for line in response.content:
+ if line:
+ messages = line.decode('utf-8').split('\x1e')
+ for message_str in messages:
+ try:
+ message = json.loads(message_str)
+ if message.get('message'):
+ full_response = message['message']
+ if message.get('finish'):
+ yield full_response.strip()
+ return
+ except json.JSONDecodeError:
+ pass
diff --git a/g4f/Provider/nexra/NexraChatGPTWeb.py b/g4f/Provider/nexra/NexraChatGPTWeb.py
new file mode 100644
index 00000000..e7738665
--- /dev/null
+++ b/g4f/Provider/nexra/NexraChatGPTWeb.py
@@ -0,0 +1,53 @@
+from __future__ import annotations
+from aiohttp import ClientSession
+from ...typing import AsyncResult, Messages
+from ..base_provider import AsyncGeneratorProvider, ProviderModelMixin
+from ..helper import format_prompt
+import json
+
+class NexraChatGPTWeb(AsyncGeneratorProvider, ProviderModelMixin):
+ label = "Nexra ChatGPT Web"
+ api_endpoint = "https://nexra.aryahcr.cc/api/chat/gptweb"
+ models = ['gptweb']
+
+ @classmethod
+ async def create_async_generator(
+ cls,
+ model: str,
+ messages: Messages,
+ proxy: str = None,
+ **kwargs
+ ) -> AsyncResult:
+ headers = {
+ "Content-Type": "application/json",
+ }
+
+ async with ClientSession(headers=headers) as session:
+ prompt = format_prompt(messages)
+ if prompt is None:
+ raise ValueError("Prompt cannot be None")
+
+ data = {
+ "prompt": prompt,
+ "markdown": False
+ }
+
+ async with session.post(cls.api_endpoint, json=data, proxy=proxy) as response:
+ response.raise_for_status()
+
+ full_response = ""
+ async for chunk in response.content:
+ if chunk:
+ result = chunk.decode("utf-8").strip()
+
+ try:
+ json_data = json.loads(result)
+
+ if json_data.get("status"):
+ full_response = json_data.get("gpt", "")
+ else:
+ full_response = f"Error: {json_data.get('message', 'Unknown error')}"
+ except json.JSONDecodeError:
+ full_response = "Error: Invalid JSON response."
+
+ yield full_response.strip()
diff --git a/g4f/Provider/nexra/NexraGeminiPro.py b/g4f/Provider/nexra/NexraGeminiPro.py
new file mode 100644
index 00000000..a57daed4
--- /dev/null
+++ b/g4f/Provider/nexra/NexraGeminiPro.py
@@ -0,0 +1,52 @@
+from __future__ import annotations
+
+import json
+from aiohttp import ClientSession
+
+from ...typing import AsyncResult, Messages
+from ..base_provider import AsyncGeneratorProvider, ProviderModelMixin
+from ..helper import format_prompt
+
+
+class NexraGeminiPro(AsyncGeneratorProvider, ProviderModelMixin):
+ label = "Nexra Gemini PRO"
+ api_endpoint = "https://nexra.aryahcr.cc/api/chat/complements"
+ models = ['gemini-pro']
+
+ @classmethod
+ async def create_async_generator(
+ cls,
+ model: str,
+ messages: Messages,
+ proxy: str = None,
+ **kwargs
+ ) -> AsyncResult:
+ headers = {
+ "Content-Type": "application/json"
+ }
+ async with ClientSession(headers=headers) as session:
+ data = {
+ "messages": [
+ {'role': 'assistant', 'content': ''},
+ {'role': 'user', 'content': format_prompt(messages)}
+ ],
+ "markdown": False,
+ "stream": True,
+ "model": model
+ }
+ async with session.post(cls.api_endpoint, json=data, proxy=proxy) as response:
+ response.raise_for_status()
+ full_response = ''
+ async for line in response.content:
+ if line:
+ messages = line.decode('utf-8').split('\x1e')
+ for message_str in messages:
+ try:
+ message = json.loads(message_str)
+ if message.get('message'):
+ full_response = message['message']
+ if message.get('finish'):
+ yield full_response.strip()
+ return
+ except json.JSONDecodeError:
+ pass
diff --git a/g4f/Provider/nexra/NexraImageURL.py b/g4f/Provider/nexra/NexraImageURL.py
new file mode 100644
index 00000000..13d70757
--- /dev/null
+++ b/g4f/Provider/nexra/NexraImageURL.py
@@ -0,0 +1,46 @@
+from __future__ import annotations
+from aiohttp import ClientSession
+import json
+from ...typing import AsyncResult, Messages
+from ..base_provider import AsyncGeneratorProvider, ProviderModelMixin
+from ..helper import format_prompt
+from ...image import ImageResponse
+
+class NexraImageURL(AsyncGeneratorProvider, ProviderModelMixin):
+ label = "Image Generation Provider"
+ api_endpoint = "https://nexra.aryahcr.cc/api/image/complements"
+ models = ['dalle', 'dalle2', 'dalle-mini', 'emi', 'sdxl-turbo', 'prodia']
+
+ @classmethod
+ async def create_async_generator(
+ cls,
+ model: str,
+ messages: Messages,
+ proxy: str = None,
+ **kwargs
+ ) -> AsyncResult:
+ headers = {
+ "Content-Type": "application/json",
+ }
+
+ async with ClientSession(headers=headers) as session:
+ prompt = format_prompt(messages)
+ data = {
+ "prompt": prompt,
+ "model": model,
+ "response": "url"
+ }
+
+ async with session.post(cls.api_endpoint, json=data, proxy=proxy) as response:
+ response.raise_for_status()
+ response_text = await response.text()
+
+ cleaned_response = response_text.lstrip('_')
+ response_json = json.loads(cleaned_response)
+
+ images = response_json.get("images")
+ if images and len(images) > 0:
+ image_response = ImageResponse(images[0], alt="Generated Image")
+ yield image_response
+ else:
+ yield "No image URL found."
diff --git a/g4f/Provider/nexra/NexraLlama.py b/g4f/Provider/nexra/NexraLlama.py
new file mode 100644
index 00000000..9ed892e8
--- /dev/null
+++ b/g4f/Provider/nexra/NexraLlama.py
@@ -0,0 +1,52 @@
+from __future__ import annotations
+
+import json
+from aiohttp import ClientSession
+
+from ...typing import AsyncResult, Messages
+from ..base_provider import AsyncGeneratorProvider, ProviderModelMixin
+from ..helper import format_prompt
+
+
+class NexraLlama(AsyncGeneratorProvider, ProviderModelMixin):
+ label = "Nexra LLaMA 3.1"
+ api_endpoint = "https://nexra.aryahcr.cc/api/chat/complements"
+ models = ['llama-3.1']
+
+ @classmethod
+ async def create_async_generator(
+ cls,
+ model: str,
+ messages: Messages,
+ proxy: str = None,
+ **kwargs
+ ) -> AsyncResult:
+ headers = {
+ "Content-Type": "application/json"
+ }
+ async with ClientSession(headers=headers) as session:
+ data = {
+ "messages": [
+ {'role': 'assistant', 'content': ''},
+ {'role': 'user', 'content': format_prompt(messages)}
+ ],
+ "markdown": False,
+ "stream": True,
+ "model": model
+ }
+ async with session.post(cls.api_endpoint, json=data, proxy=proxy) as response:
+ response.raise_for_status()
+ full_response = ''
+ async for line in response.content:
+ if line:
+ messages = line.decode('utf-8').split('\x1e')
+ for message_str in messages:
+ try:
+ message = json.loads(message_str)
+ if message.get('message'):
+ full_response = message['message']
+ if message.get('finish'):
+ yield full_response.strip()
+ return
+ except json.JSONDecodeError:
+ pass
diff --git a/g4f/Provider/nexra/NexraQwen.py b/g4f/Provider/nexra/NexraQwen.py
new file mode 100644
index 00000000..ae8e9a0e
--- /dev/null
+++ b/g4f/Provider/nexra/NexraQwen.py
@@ -0,0 +1,52 @@
+from __future__ import annotations
+
+import json
+from aiohttp import ClientSession
+
+from ...typing import AsyncResult, Messages
+from ..base_provider import AsyncGeneratorProvider, ProviderModelMixin
+from ..helper import format_prompt
+
+
+class NexraQwen(AsyncGeneratorProvider, ProviderModelMixin):
+ label = "Nexra Qwen"
+ api_endpoint = "https://nexra.aryahcr.cc/api/chat/complements"
+ models = ['qwen']
+
+ @classmethod
+ async def create_async_generator(
+ cls,
+ model: str,
+ messages: Messages,
+ proxy: str = None,
+ **kwargs
+ ) -> AsyncResult:
+ headers = {
+ "Content-Type": "application/json"
+ }
+ async with ClientSession(headers=headers) as session:
+ data = {
+ "messages": [
+ {'role': 'assistant', 'content': ''},
+ {'role': 'user', 'content': format_prompt(messages)}
+ ],
+ "markdown": False,
+ "stream": True,
+ "model": model
+ }
+ async with session.post(cls.api_endpoint, json=data, proxy=proxy) as response:
+ response.raise_for_status()
+ full_response = ''
+ async for line in response.content:
+ if line:
+ messages = line.decode('utf-8').split('\x1e')
+ for message_str in messages:
+ try:
+ message = json.loads(message_str)
+ if message.get('message'):
+ full_response = message['message']
+ if message.get('finish'):
+ yield full_response.strip()
+ return
+ except json.JSONDecodeError:
+ pass
diff --git a/g4f/Provider/nexra/__init__.py b/g4f/Provider/nexra/__init__.py
new file mode 100644
index 00000000..8b137891
--- /dev/null
+++ b/g4f/Provider/nexra/__init__.py
@@ -0,0 +1 @@
+
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/AItianhuSpace.py b/g4f/Provider/selenium/AItianhuSpace.py
deleted file mode 100644
index 4c438e3b..00000000
--- a/g4f/Provider/selenium/AItianhuSpace.py
+++ /dev/null
@@ -1,116 +0,0 @@
-from __future__ import annotations
-
-import time
-import random
-
-from ...typing import CreateResult, Messages
-from ..base_provider import AbstractProvider
-from ..helper import format_prompt, get_random_string
-from ...webdriver import WebDriver, WebDriverSession, element_send_text
-from ... import debug
-
-class AItianhuSpace(AbstractProvider):
- url = "https://chat3.aiyunos.top/"
- working = True
- supports_stream = True
- supports_gpt_35_turbo = True
- _domains = ["aitianhu.com", "aitianhu1.top"]
-
- @classmethod
- def create_completion(
- cls,
- model: str,
- messages: Messages,
- stream: bool,
- domain: str = None,
- proxy: str = None,
- timeout: int = 120,
- webdriver: WebDriver = None,
- headless: bool = True,
- **kwargs
- ) -> CreateResult:
- if not model:
- model = "gpt-3.5-turbo"
- if not domain:
- rand = get_random_string(6)
- domain = random.choice(cls._domains)
- domain = f"{rand}.{domain}"
- if debug.logging:
- print(f"AItianhuSpace | using domain: {domain}")
- url = f"https://{domain}"
- prompt = format_prompt(messages)
-
- with WebDriverSession(webdriver, "", headless=headless, proxy=proxy) as driver:
- from selenium.webdriver.common.by import By
- from selenium.webdriver.support.ui import WebDriverWait
- from selenium.webdriver.support import expected_conditions as EC
-
- wait = WebDriverWait(driver, timeout)
-
- # Bypass devtools detection
- driver.get("https://blank.page/")
- wait.until(EC.visibility_of_element_located((By.ID, "sheet")))
- driver.execute_script(f"""
- document.getElementById('sheet').addEventListener('click', () => {{
- window.open(arguments[0]);
- }});
- """, url)
- driver.find_element(By.ID, "sheet").click()
- time.sleep(10)
-
- original_window = driver.current_window_handle
- for window_handle in driver.window_handles:
- if window_handle != original_window:
- driver.close()
- driver.switch_to.window(window_handle)
- break
-
- # Wait for page load
- wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "textarea.n-input__textarea-el")))
-
- # Register hook in XMLHttpRequest
- script = """
-const _http_request_open = XMLHttpRequest.prototype.open;
-window._last_message = window._message = "";
-window._loadend = false;
-XMLHttpRequest.prototype.open = function(method, url) {
- if (url == "/api/chat-process") {
- this.addEventListener("progress", (event) => {
- const lines = this.responseText.split("\\n");
- try {
- window._message = JSON.parse(lines[lines.length-1])["text"];
- } catch(e) { }
- });
- this.addEventListener("loadend", (event) => {
- window._loadend = true;
- });
- }
- return _http_request_open.call(this, method, url);
-}
-"""
- driver.execute_script(script)
-
- # Submit prompt
- element_send_text(driver.find_element(By.CSS_SELECTOR, "textarea.n-input__textarea-el"), prompt)
-
- # Read response
- while True:
- chunk = driver.execute_script("""
-if (window._message && window._message != window._last_message) {
- try {
- return window._message.substring(window._last_message.length);
- } finally {
- window._last_message = window._message;
- }
-}
-if (window._loadend) {
- return null;
-}
-return "";
-""")
- if chunk:
- yield chunk
- elif chunk != "":
- break
- else:
- time.sleep(0.1) \ 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 9a020460..3a59ea58 100644
--- a/g4f/Provider/selenium/__init__.py
+++ b/g4f/Provider/selenium/__init__.py
@@ -1,6 +1,4 @@
-from .AItianhuSpace import AItianhuSpace
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
diff --git a/g4f/client/async_client.py b/g4f/client/async_client.py
index 2fe4640b..9caa74b2 100644
--- a/g4f/client/async_client.py
+++ b/g4f/client/async_client.py
@@ -1,32 +1,37 @@
from __future__ import annotations
+import os
import time
import random
import string
+import logging
import asyncio
-import base64
-from aiohttp import ClientSession, BaseConnector
-
-from .types import Client as BaseClient
-from .types import ProviderType, FinishReason
-from .stubs import ChatCompletion, ChatCompletionChunk, ImagesResponse, Image
-from .types import AsyncIterResponse, ImageProvider
-from .image_models import ImageModels
-from .helper import filter_json, find_stop, filter_none, cast_iter_async
-from .service import get_last_provider, get_model_and_provider
-from ..Provider import ProviderUtils
-from ..typing import Union, Messages, AsyncIterator, ImageType
-from ..errors import NoImageResponseError, ProviderNotFoundError
-from ..requests.aiohttp import get_connector
+from typing import Union, AsyncIterator
+from ..providers.base_provider import AsyncGeneratorProvider
+from ..image import ImageResponse, to_image, to_data_uri
+from ..typing import Messages, ImageType
+from ..providers.types import BaseProvider, ProviderType, FinishReason
from ..providers.conversation import BaseConversation
-from ..image import ImageResponse as ImageProviderResponse, ImageDataResponse
+from ..image import ImageResponse as ImageProviderResponse
+from ..errors import NoImageResponseError
+from .stubs import ChatCompletion, ChatCompletionChunk, Image, ImagesResponse
+from .image_models import ImageModels
+from .types import IterResponse, ImageProvider
+from .types import Client as BaseClient
+from .service import get_model_and_provider, get_last_provider
+from .helper import find_stop, filter_json, filter_none
+from ..models import ModelUtils
+from ..Provider import IterListProvider
+from .helper import cast_iter_async
try:
- anext
+ anext # Python 3.8+
except NameError:
- async def anext(iter):
- async for chunk in iter:
- return chunk
+ async def anext(aiter):
+ try:
+ return await aiter.__anext__()
+ except StopAsyncIteration:
+ raise StopIteration
async def iter_response(
response: AsyncIterator[str],
@@ -34,11 +39,12 @@ async def iter_response(
response_format: dict = None,
max_tokens: int = None,
stop: list = None
-) -> AsyncIterResponse:
+) -> AsyncIterator[Union[ChatCompletion, ChatCompletionChunk]]:
content = ""
finish_reason = None
completion_id = ''.join(random.choices(string.ascii_letters + string.digits, k=28))
- count: int = 0
+ idx = 0
+
async for chunk in response:
if isinstance(chunk, FinishReason):
finish_reason = chunk.reason
@@ -46,18 +52,26 @@ async def iter_response(
elif isinstance(chunk, BaseConversation):
yield chunk
continue
+
content += str(chunk)
- count += 1
- if max_tokens is not None and count >= max_tokens:
+ idx += 1
+
+ if max_tokens is not None and idx >= max_tokens:
finish_reason = "length"
- first, content, chunk = find_stop(stop, content, chunk)
+
+ first, content, chunk = find_stop(stop, content, chunk if stream else None)
+
if first != -1:
finish_reason = "stop"
+
if stream:
yield ChatCompletionChunk(chunk, None, completion_id, int(time.time()))
+
if finish_reason is not None:
break
+
finish_reason = "stop" if finish_reason is None else finish_reason
+
if stream:
yield ChatCompletionChunk(None, finish_reason, completion_id, int(time.time()))
else:
@@ -66,12 +80,12 @@ async def iter_response(
content = filter_json(content)
yield ChatCompletion(content, finish_reason, completion_id, int(time.time()))
-async def iter_append_model_and_provider(response: AsyncIterResponse) -> AsyncIterResponse:
+async def iter_append_model_and_provider(response: AsyncIterator) -> AsyncIterator:
last_provider = None
async for chunk in response:
last_provider = get_last_provider(True) if last_provider is None else last_provider
chunk.model = last_provider.get("model")
- chunk.provider = last_provider.get("name")
+ chunk.provider = last_provider.get("name")
yield chunk
class AsyncClient(BaseClient):
@@ -80,59 +94,32 @@ class AsyncClient(BaseClient):
provider: ProviderType = None,
image_provider: ImageProvider = None,
**kwargs
- ):
+ ) -> None:
super().__init__(**kwargs)
self.chat: Chat = Chat(self, provider)
- self.images: Images = Images(self, image_provider)
-
-def create_response(
- messages: Messages,
- model: str,
- provider: ProviderType = None,
- stream: bool = False,
- proxy: str = None,
- max_tokens: int = None,
- stop: list[str] = None,
- api_key: str = None,
- **kwargs
-):
- has_asnyc = hasattr(provider, "create_async_generator")
- if has_asnyc:
- create = provider.create_async_generator
- else:
- create = provider.create_completion
- response = create(
- model, messages,
- stream=stream,
- **filter_none(
- proxy=proxy,
- max_tokens=max_tokens,
- stop=stop,
- api_key=api_key
- ),
- **kwargs
- )
- if not has_asnyc:
- response = cast_iter_async(response)
- return response
+ self._images: Images = Images(self, image_provider)
-class Completions():
- def __init__(self, client: AsyncClient, provider: ProviderType = None):
- self.client: AsyncClient = client
+ @property
+ def images(self) -> Images:
+ return self._images
+
+class Completions:
+ def __init__(self, client: 'AsyncClient', provider: ProviderType = None):
+ self.client: 'AsyncClient' = client
self.provider: ProviderType = provider
- def create(
+ async def create(
self,
messages: Messages,
model: str,
provider: ProviderType = None,
stream: bool = False,
proxy: str = None,
+ response_format: dict = None,
max_tokens: int = None,
stop: Union[list[str], str] = None,
api_key: str = None,
- response_format: dict = None,
- ignored : list[str] = None,
+ ignored: list[str] = None,
ignore_working: bool = False,
ignore_stream: bool = False,
**kwargs
@@ -143,133 +130,171 @@ class Completions():
stream,
ignored,
ignore_working,
- ignore_stream
+ ignore_stream,
)
+
stop = [stop] if isinstance(stop, str) else stop
- response = create_response(
- messages, model,
- provider, stream,
- proxy=self.client.get_proxy() if proxy is None else proxy,
- max_tokens=max_tokens,
- stop=stop,
- api_key=self.client.api_key if api_key is None else api_key,
+
+ response = provider.create_completion(
+ model,
+ messages,
+ stream=stream,
+ **filter_none(
+ proxy=self.client.get_proxy() if proxy is None else proxy,
+ max_tokens=max_tokens,
+ stop=stop,
+ api_key=self.client.api_key if api_key is None else api_key
+ ),
**kwargs
)
- response = iter_response(response, stream, response_format, max_tokens, stop)
- response = iter_append_model_and_provider(response)
- return response if stream else anext(response)
-class Chat():
+ if isinstance(response, AsyncIterator):
+ response = iter_response(response, stream, response_format, max_tokens, stop)
+ response = iter_append_model_and_provider(response)
+ return response if stream else await anext(response)
+ else:
+ response = cast_iter_async(response)
+ response = iter_response(response, stream, response_format, max_tokens, stop)
+ response = iter_append_model_and_provider(response)
+ return response if stream else await anext(response)
+
+
+
+class Chat:
completions: Completions
def __init__(self, client: AsyncClient, provider: ProviderType = None):
self.completions = Completions(client, provider)
-async def iter_image_response(
- response: AsyncIterator,
- response_format: str = None,
- connector: BaseConnector = None,
- proxy: str = None
-) -> Union[ImagesResponse, None]:
+async def iter_image_response(response: AsyncIterator) -> Union[ImagesResponse, None]:
+ logging.info("Starting iter_image_response")
async for chunk in response:
+ logging.info(f"Processing chunk: {chunk}")
if isinstance(chunk, ImageProviderResponse):
- if response_format == "b64_json":
- async with ClientSession(
- connector=get_connector(connector, proxy),
- cookies=chunk.options.get("cookies")
- ) as session:
- async def fetch_image(image):
- async with session.get(image) as response:
- return base64.b64encode(await response.content.read()).decode()
- images = await asyncio.gather(*[fetch_image(image) for image in chunk.get_list()])
- return ImagesResponse([Image(None, image, chunk.alt) for image in images], int(time.time()))
- return ImagesResponse([Image(image, None, chunk.alt) for image in chunk.get_list()], int(time.time()))
- elif isinstance(chunk, ImageDataResponse):
- return ImagesResponse([Image(None, image, chunk.alt) for image in chunk.get_list()], int(time.time()))
-
-def create_image(provider: ProviderType, prompt: str, model: str = "", **kwargs) -> AsyncIterator:
+ logging.info("Found ImageProviderResponse")
+ return ImagesResponse([Image(image) for image in chunk.get_list()])
+
+ logging.warning("No ImageProviderResponse found in the response")
+ return None
+
+async def create_image(client: AsyncClient, provider: ProviderType, prompt: str, model: str = "", **kwargs) -> AsyncIterator:
+ logging.info(f"Creating image with provider: {provider}, model: {model}, prompt: {prompt}")
+
if isinstance(provider, type) and provider.__name__ == "You":
kwargs["chat_mode"] = "create"
else:
- prompt = f"create a image with: {prompt}"
- return provider.create_async_generator(
+ prompt = f"create an image with: {prompt}"
+
+ response = await provider.create_completion(
model,
[{"role": "user", "content": prompt}],
stream=True,
+ proxy=client.get_proxy(),
**kwargs
)
+
+ logging.info(f"Response from create_completion: {response}")
+ return response
-class Images():
- def __init__(self, client: AsyncClient, provider: ImageProvider = None):
- self.client: AsyncClient = client
+class Images:
+ def __init__(self, client: 'AsyncClient', provider: ImageProvider = None):
+ self.client: 'AsyncClient' = client
self.provider: ImageProvider = provider
self.models: ImageModels = ImageModels(client)
- def get_provider(self, model: str, provider: ProviderType = None):
- if isinstance(provider, str):
- if provider in ProviderUtils.convert:
- provider = ProviderUtils.convert[provider]
+ async def generate(self, prompt: str, model: str = None, **kwargs) -> ImagesResponse:
+ logging.info(f"Starting asynchronous image generation for model: {model}, prompt: {prompt}")
+ provider = self.models.get(model, self.provider)
+ if provider is None:
+ raise ValueError(f"Unknown model: {model}")
+
+ logging.info(f"Provider: {provider}")
+
+ if isinstance(provider, IterListProvider):
+ if provider.providers:
+ provider = provider.providers[0]
+ logging.info(f"Using first provider from IterListProvider: {provider}")
+ else:
+ raise ValueError(f"IterListProvider for model {model} has no providers")
+
+ if isinstance(provider, type) and issubclass(provider, AsyncGeneratorProvider):
+ logging.info("Using AsyncGeneratorProvider")
+ messages = [{"role": "user", "content": prompt}]
+ async for response in provider.create_async_generator(model, messages, **kwargs):
+ if isinstance(response, ImageResponse):
+ return self._process_image_response(response)
+ elif isinstance(response, str):
+ image_response = ImageResponse([response], prompt)
+ return self._process_image_response(image_response)
+ elif hasattr(provider, 'create'):
+ logging.info("Using provider's create method")
+ async_create = asyncio.iscoroutinefunction(provider.create)
+ if async_create:
+ response = await provider.create(prompt)
else:
- raise ProviderNotFoundError(f'Provider not found: {provider}')
+ response = provider.create(prompt)
+
+ if isinstance(response, ImageResponse):
+ return self._process_image_response(response)
+ elif isinstance(response, str):
+ image_response = ImageResponse([response], prompt)
+ return self._process_image_response(image_response)
+ elif hasattr(provider, 'create_completion'):
+ logging.info("Using provider's create_completion method")
+ response = await create_image(provider, prompt, model, **kwargs)
+ async for chunk in response:
+ if isinstance(chunk, ImageProviderResponse):
+ logging.info("Found ImageProviderResponse")
+ return ImagesResponse([Image(image) for image in chunk.get_list()])
else:
- provider = self.models.get(model, self.provider)
- return provider
+ raise ValueError(f"Provider {provider} does not support image generation")
- async def generate(
- self,
- prompt,
- model: str = "",
- provider: ProviderType = None,
- response_format: str = None,
- connector: BaseConnector = None,
- proxy: str = None,
- **kwargs
- ) -> ImagesResponse:
- provider = self.get_provider(model, provider)
- if hasattr(provider, "create_async_generator"):
- response = create_image(
- provider,
- prompt,
- **filter_none(
- response_format=response_format,
- connector=connector,
- proxy=self.client.get_proxy() if proxy is None else proxy,
- ),
- **kwargs
- )
+ logging.error(f"Unexpected response type: {type(response)}")
+ raise NoImageResponseError(f"Unexpected response type: {type(response)}")
+
+ def _process_image_response(self, response: ImageResponse) -> ImagesResponse:
+ processed_images = []
+ for image_data in response.get_list():
+ if image_data.startswith('http://') or image_data.startswith('https://'):
+ processed_images.append(Image(url=image_data))
+ else:
+ image = to_image(image_data)
+ file_name = self._save_image(image)
+ processed_images.append(Image(url=file_name))
+ return ImagesResponse(processed_images)
+
+ def _save_image(self, image: 'PILImage') -> str:
+ os.makedirs('generated_images', exist_ok=True)
+ file_name = f"generated_images/image_{int(time.time())}.png"
+ image.save(file_name)
+ return file_name
+
+ async def create_variation(self, image: Union[str, bytes], model: str = None, **kwargs) -> ImagesResponse:
+ provider = self.models.get(model, self.provider)
+ if provider is None:
+ raise ValueError(f"Unknown model: {model}")
+
+ if isinstance(provider, type) and issubclass(provider, AsyncGeneratorProvider):
+ messages = [{"role": "user", "content": "create a variation of this image"}]
+ image_data = to_data_uri(image)
+ async for response in provider.create_async_generator(model, messages, image=image_data, **kwargs):
+ if isinstance(response, ImageResponse):
+ return self._process_image_response(response)
+ elif isinstance(response, str):
+ image_response = ImageResponse([response], "Image variation")
+ return self._process_image_response(image_response)
+ elif hasattr(provider, 'create_variation'):
+ if asyncio.iscoroutinefunction(provider.create_variation):
+ response = await provider.create_variation(image, **kwargs)
+ else:
+ response = provider.create_variation(image, **kwargs)
+
+ if isinstance(response, ImageResponse):
+ return self._process_image_response(response)
+ elif isinstance(response, str):
+ image_response = ImageResponse([response], "Image variation")
+ return self._process_image_response(image_response)
else:
- response = await provider.create_async(prompt)
- return ImagesResponse([Image(image) for image in response.get_list()])
- image = await iter_image_response(response, response_format, connector, proxy)
- if image is None:
- raise NoImageResponseError()
- return image
-
- async def create_variation(
- self,
- image: ImageType,
- model: str = None,
- response_format: str = None,
- connector: BaseConnector = None,
- proxy: str = None,
- **kwargs
- ):
- provider = self.get_provider(model, provider)
- result = None
- if hasattr(provider, "create_async_generator"):
- response = provider.create_async_generator(
- "",
- [{"role": "user", "content": "create a image like this"}],
- stream=True,
- image=image,
- **filter_none(
- response_format=response_format,
- connector=connector,
- proxy=self.client.get_proxy() if proxy is None else proxy,
- ),
- **kwargs
- )
- result = iter_image_response(response, response_format, connector, proxy)
- if result is None:
- raise NoImageResponseError()
- return result
+ raise ValueError(f"Provider {provider} does not support image variation")
+
+ raise NoImageResponseError("Failed to create image variation")
diff --git a/g4f/gui/client/static/css/style.css b/g4f/gui/client/static/css/style.css
index f3a4708d..e185c0fe 100644
--- a/g4f/gui/client/static/css/style.css
+++ b/g4f/gui/client/static/css/style.css
@@ -91,7 +91,6 @@ body {
background: var(--colour-1);
color: var(--colour-3);
height: 100vh;
- max-width: 1600px;
margin: auto;
}
@@ -1146,4 +1145,4 @@ a:-webkit-any-link {
.message.regenerate {
opacity: 1;
}
-} \ No newline at end of file
+}
diff --git a/g4f/models.py b/g4f/models.py
index ddbeeddf..2940b96a 100644
--- a/g4f/models.py
+++ b/g4f/models.py
@@ -4,21 +4,23 @@ from dataclasses import dataclass
from .Provider import IterListProvider, ProviderType
from .Provider import (
- AiChatOnline,
+ AIChatFree,
+ Airforce,
Allyfy,
Bing,
Binjie,
Bixin123,
Blackbox,
- ChatGot,
- Chatgpt4Online,
+ ChatGpt,
Chatgpt4o,
+ Chatgpt4Online,
+ ChatGptEs,
ChatgptFree,
- CodeNews,
+ ChatHub,
DDG,
DeepInfra,
+ DeepInfraChat,
DeepInfraImage,
- FluxAirforce,
Free2GPT,
FreeChatgpt,
FreeGpt,
@@ -26,10 +28,12 @@ from .Provider import (
Gemini,
GeminiPro,
GigaChat,
+ GPROChat,
HuggingChat,
HuggingFace,
Koala,
Liaobots,
+ LiteIcoding,
MagickPen,
MetaAI,
Nexra,
@@ -40,9 +44,7 @@ from .Provider import (
Reka,
Replicate,
ReplicateHome,
- Snova,
TeachAnything,
- TwitterBio,
Upstage,
You,
)
@@ -75,7 +77,6 @@ default = Model(
FreeChatgpt,
HuggingChat,
Pizzagpt,
- ChatgptFree,
ReplicateHome,
Upstage,
Blackbox,
@@ -83,6 +84,8 @@ default = Model(
Binjie,
Free2GPT,
MagickPen,
+ DeepInfraChat,
+ LiteIcoding,
])
)
@@ -95,9 +98,7 @@ default = Model(
gpt_3 = Model(
name = 'gpt-3',
base_provider = 'OpenAI',
- best_provider = IterListProvider([
- Nexra,
- ])
+ best_provider = Nexra
)
# gpt-3.5
@@ -105,7 +106,7 @@ gpt_35_turbo = Model(
name = 'gpt-3.5-turbo',
base_provider = 'OpenAI',
best_provider = IterListProvider([
- Allyfy, TwitterBio, Nexra, Bixin123, CodeNews,
+ Allyfy, Nexra, Bixin123, Airforce,
])
)
@@ -114,7 +115,8 @@ gpt_4o = Model(
name = 'gpt-4o',
base_provider = 'OpenAI',
best_provider = IterListProvider([
- Liaobots, Chatgpt4o, OpenaiChat,
+ Liaobots, Nexra, Airforce, Chatgpt4o, ChatGptEs,
+ OpenaiChat
])
)
@@ -122,8 +124,8 @@ gpt_4o_mini = Model(
name = 'gpt-4o-mini',
base_provider = 'OpenAI',
best_provider = IterListProvider([
- DDG, Liaobots, You, FreeNetfly, Pizzagpt, ChatgptFree, AiChatOnline, CodeNews,
- MagickPen, OpenaiChat, Koala,
+ DDG, ChatGptEs, You, FreeNetfly, Pizzagpt, LiteIcoding, MagickPen, Liaobots, Airforce, ChatgptFree, Koala,
+ OpenaiChat, ChatGpt
])
)
@@ -131,7 +133,7 @@ gpt_4_turbo = Model(
name = 'gpt-4-turbo',
base_provider = 'OpenAI',
best_provider = IterListProvider([
- Nexra, Bixin123, Liaobots, Bing
+ Nexra, Bixin123, Liaobots, Airforce, Bing
])
)
@@ -139,11 +141,13 @@ gpt_4 = Model(
name = 'gpt-4',
base_provider = 'OpenAI',
best_provider = IterListProvider([
- Chatgpt4Online, Nexra, Binjie, Bing,
- gpt_4_turbo.best_provider, gpt_4o.best_provider, gpt_4o_mini.best_provider
+ Nexra, Binjie, Airforce,
+ gpt_4_turbo.best_provider, gpt_4o.best_provider, gpt_4o_mini.best_provider,
+ Chatgpt4Online, Bing, OpenaiChat,
])
)
+
### GigaChat ###
gigachat = Model(
name = 'GigaChat:latest',
@@ -159,136 +163,224 @@ meta = Model(
best_provider = MetaAI
)
+# llama 2
+llama_2_13b = Model(
+ name = "llama-2-13b",
+ base_provider = "Meta Llama",
+ best_provider = Airforce
+)
+
+# llama 3
llama_3_8b = Model(
name = "llama-3-8b",
- base_provider = "Meta",
- best_provider = IterListProvider([DeepInfra, Replicate])
+ base_provider = "Meta Llama",
+ best_provider = IterListProvider([Airforce, DeepInfra, Replicate])
)
llama_3_70b = Model(
name = "llama-3-70b",
- base_provider = "Meta",
- best_provider = IterListProvider([ReplicateHome, DeepInfra, PerplexityLabs, Replicate])
+ base_provider = "Meta Llama",
+ best_provider = IterListProvider([ReplicateHome, Airforce, DeepInfra, Replicate])
+)
+
+llama_3 = Model(
+ name = "llama-3",
+ base_provider = "Meta Llama",
+ best_provider = IterListProvider([llama_3_8b.best_provider, llama_3_70b.best_provider])
)
+# llama 3.1
llama_3_1_8b = Model(
name = "llama-3.1-8b",
- base_provider = "Meta",
- best_provider = IterListProvider([Blackbox])
+ base_provider = "Meta Llama",
+ best_provider = IterListProvider([Blackbox, DeepInfraChat, ChatHub, Airforce, PerplexityLabs])
)
llama_3_1_70b = Model(
name = "llama-3.1-70b",
- base_provider = "Meta",
- best_provider = IterListProvider([DDG, HuggingChat, FreeGpt, Blackbox, TeachAnything, Free2GPT, HuggingFace])
+ base_provider = "Meta Llama",
+ best_provider = IterListProvider([DDG, HuggingChat, Blackbox, FreeGpt, TeachAnything, Free2GPT, DeepInfraChat, Airforce, HuggingFace, PerplexityLabs])
)
llama_3_1_405b = Model(
name = "llama-3.1-405b",
- base_provider = "Meta",
- best_provider = IterListProvider([HuggingChat, Blackbox, HuggingFace])
+ base_provider = "Meta Llama",
+ best_provider = IterListProvider([Blackbox, DeepInfraChat, Airforce])
+)
+
+llama_3_1 = Model(
+ name = "llama-3.1",
+ base_provider = "Meta Llama",
+ best_provider = IterListProvider([Nexra, llama_3_1_8b.best_provider, llama_3_1_70b.best_provider, llama_3_1_405b.best_provider,])
)
+
### Mistral ###
+mistral_7b = Model(
+ name = "mistral-7b",
+ base_provider = "Mistral",
+ best_provider = IterListProvider([HuggingChat, DeepInfraChat, Airforce, HuggingFace, DeepInfra])
+)
+
mixtral_8x7b = Model(
name = "mixtral-8x7b",
base_provider = "Mistral",
- best_provider = IterListProvider([HuggingChat, DDG, ReplicateHome, TwitterBio, DeepInfra, HuggingFace,])
+ best_provider = IterListProvider([DDG, ReplicateHome, DeepInfraChat, ChatHub, Airforce, DeepInfra])
)
-mistral_7b = Model(
- name = "mistral-7b",
+mixtral_8x22b = Model(
+ name = "mixtral-8x22b",
base_provider = "Mistral",
- best_provider = IterListProvider([HuggingChat, HuggingFace, DeepInfra])
+ best_provider = IterListProvider([DeepInfraChat, Airforce])
)
-### 01-ai ###
-yi_1_5_34b = Model(
- name = "yi-1.5-34b",
- base_provider = "01-ai",
+mistral_nemo = Model(
+ name = "mistral-nemo",
+ base_provider = "Mistral",
+ best_provider = IterListProvider([HuggingChat, HuggingFace])
+)
+
+
+### NousResearch ###
+mixtral_8x7b_dpo = Model(
+ name = "mixtral-8x7b-dpo",
+ base_provider = "NousResearch",
+ best_provider = Airforce
+)
+
+hermes_3 = Model(
+ name = "hermes-3",
+ base_provider = "NousResearch",
best_provider = IterListProvider([HuggingChat, HuggingFace])
)
### Microsoft ###
-phi_3_mini_4k = Model(
- name = "phi-3-mini-4k",
+phi_3_medium_4k = Model(
+ name = "phi-3-medium-4k",
base_provider = "Microsoft",
- best_provider = IterListProvider([HuggingFace, HuggingChat])
+ best_provider = DeepInfraChat
)
+phi_3_5_mini = Model(
+ name = "phi-3.5-mini",
+ base_provider = "Microsoft",
+ best_provider = IterListProvider([HuggingChat, HuggingFace])
+)
-### Google ###
+### Google DeepMind ###
# gemini
+gemini_pro = Model(
+ name = 'gemini-pro',
+ base_provider = 'Google DeepMind',
+ best_provider = IterListProvider([GeminiPro, LiteIcoding, Blackbox, AIChatFree, GPROChat, Nexra, Liaobots, Airforce])
+)
+
+gemini_flash = Model(
+ name = 'gemini-flash',
+ base_provider = 'Google DeepMind',
+ best_provider = IterListProvider([Blackbox, Liaobots, Airforce])
+)
+
gemini = Model(
name = 'gemini',
- base_provider = 'Google',
- best_provider = Gemini
+ base_provider = 'Google DeepMind',
+ best_provider = IterListProvider([Gemini, gemini_flash.best_provider, gemini_pro.best_provider])
)
-gemini_pro = Model(
- name = 'gemini-pro',
+# gemma
+gemma_2b_9b = Model(
+ name = 'gemma-2b-9b',
base_provider = 'Google',
- best_provider = IterListProvider([GeminiPro, ChatGot, Liaobots])
+ best_provider = Airforce
)
-gemini_flash = Model(
- name = 'gemini-flash',
+gemma_2b_27b = Model(
+ name = 'gemma-2b-27b',
base_provider = 'Google',
- best_provider = IterListProvider([Liaobots, Blackbox])
+ best_provider = IterListProvider([DeepInfraChat, Airforce])
)
-# gemma
gemma_2b = Model(
name = 'gemma-2b',
base_provider = 'Google',
- best_provider = IterListProvider([ReplicateHome])
+ best_provider = IterListProvider([
+ ReplicateHome, Airforce,
+ gemma_2b_9b.best_provider, gemma_2b_27b.best_provider,
+ ])
)
+gemma_2 = Model(
+ name = 'gemma-2',
+ base_provider = 'Google',
+ best_provider = ChatHub
+)
+
+
### Anthropic ###
claude_2 = Model(
name = 'claude-2',
base_provider = 'Anthropic',
- best_provider = IterListProvider([You])
+ best_provider = You
)
claude_2_0 = Model(
name = 'claude-2.0',
base_provider = 'Anthropic',
- best_provider = IterListProvider([Liaobots])
+ best_provider = Liaobots
)
claude_2_1 = Model(
name = 'claude-2.1',
base_provider = 'Anthropic',
- best_provider = IterListProvider([Liaobots])
+ best_provider = Liaobots
)
+# claude 3
claude_3_opus = Model(
name = 'claude-3-opus',
base_provider = 'Anthropic',
- best_provider = IterListProvider([Liaobots])
+ best_provider = Liaobots
)
claude_3_sonnet = Model(
name = 'claude-3-sonnet',
base_provider = 'Anthropic',
- best_provider = IterListProvider([Liaobots])
+ best_provider = Liaobots
+)
+
+claude_3_haiku = Model(
+ name = 'claude-3-haiku',
+ base_provider = 'Anthropic',
+ best_provider = IterListProvider([DDG, Liaobots])
)
+claude_3 = Model(
+ name = 'claude-3',
+ base_provider = 'Anthropic',
+ best_provider = IterListProvider([
+ claude_3_opus.best_provider, claude_3_sonnet.best_provider, claude_3_haiku.best_provider
+ ])
+)
+
+# claude 3.5
claude_3_5_sonnet = Model(
- name = 'claude-3-5-sonnet',
+ name = 'claude-3.5-sonnet',
base_provider = 'Anthropic',
- best_provider = IterListProvider([Liaobots])
+ best_provider = IterListProvider([Blackbox, Liaobots])
)
-claude_3_haiku = Model(
- name = 'claude-3-haiku',
+claude_3_5 = Model(
+ name = 'claude-3.5',
base_provider = 'Anthropic',
- best_provider = IterListProvider([DDG, Liaobots])
+ best_provider = IterListProvider([
+ LiteIcoding,
+ claude_3_5_sonnet.best_provider
+ ])
)
+
### Reka AI ###
reka_core = Model(
name = 'reka-core',
@@ -297,10 +389,10 @@ reka_core = Model(
)
-### Blackbox ###
+### Blackbox AI ###
blackbox = Model(
name = 'blackbox',
- base_provider = 'Blackbox',
+ base_provider = 'Blackbox AI',
best_provider = Blackbox
)
@@ -309,7 +401,7 @@ blackbox = Model(
dbrx_instruct = Model(
name = 'dbrx-instruct',
base_provider = 'Databricks',
- best_provider = IterListProvider([DeepInfra])
+ best_provider = IterListProvider([Airforce, DeepInfra])
)
@@ -317,7 +409,7 @@ dbrx_instruct = Model(
command_r_plus = Model(
name = 'command-r-plus',
base_provider = 'CohereForAI',
- best_provider = IterListProvider([HuggingChat])
+ best_provider = HuggingChat
)
@@ -325,20 +417,45 @@ command_r_plus = Model(
sparkdesk_v1_1 = Model(
name = 'sparkdesk-v1.1',
base_provider = 'iFlytek',
- best_provider = IterListProvider([FreeChatgpt])
+ best_provider = IterListProvider([FreeChatgpt, Airforce])
)
+
### Qwen ###
qwen_1_5_14b = Model(
name = 'qwen-1.5-14b',
base_provider = 'Qwen',
- best_provider = IterListProvider([FreeChatgpt])
+ best_provider = FreeChatgpt
+)
+
+qwen_1_5_72b = Model(
+ name = 'qwen-1.5-72b',
+ base_provider = 'Qwen',
+ best_provider = Airforce
+)
+
+qwen_1_5_110b = Model(
+ name = 'qwen-1.5-110b',
+ base_provider = 'Qwen',
+ best_provider = Airforce
+)
+
+qwen_2_72b = Model(
+ name = 'qwen-2-72b',
+ base_provider = 'Qwen',
+ best_provider = IterListProvider([DeepInfraChat, HuggingChat, Airforce, HuggingFace])
)
qwen_turbo = Model(
name = 'qwen-turbo',
base_provider = 'Qwen',
- best_provider = IterListProvider([Bixin123])
+ best_provider = Bixin123
+)
+
+qwen = Model(
+ name = 'qwen',
+ base_provider = 'Qwen',
+ best_provider = IterListProvider([Nexra, qwen_1_5_14b.best_provider, qwen_1_5_72b.best_provider, qwen_1_5_110b.best_provider, qwen_2_72b.best_provider, qwen_turbo.best_provider])
)
@@ -346,76 +463,165 @@ qwen_turbo = Model(
glm_3_6b = Model(
name = 'glm-3-6b',
base_provider = 'Zhipu AI',
- best_provider = IterListProvider([FreeChatgpt])
+ best_provider = FreeChatgpt
)
glm_4_9b = Model(
name = 'glm-4-9B',
base_provider = 'Zhipu AI',
- best_provider = IterListProvider([FreeChatgpt])
+ best_provider = FreeChatgpt
)
glm_4 = Model(
name = 'glm-4',
base_provider = 'Zhipu AI',
- best_provider = IterListProvider([CodeNews, glm_4_9b.best_provider,])
+ best_provider = IterListProvider([
+ glm_3_6b.best_provider, glm_4_9b.best_provider
+ ])
)
+
### 01-ai ###
yi_1_5_9b = Model(
name = 'yi-1.5-9b',
base_provider = '01-ai',
- best_provider = IterListProvider([FreeChatgpt])
+ best_provider = FreeChatgpt
+)
+
+yi_34b = Model(
+ name = 'yi-34b',
+ base_provider = '01-ai',
+ best_provider = Airforce
)
-### Pi ###
+### Upstage ###
solar_1_mini = Model(
name = 'solar-1-mini',
base_provider = 'Upstage',
- best_provider = IterListProvider([Upstage])
+ best_provider = Upstage
+)
+
+solar_10_7b = Model(
+ name = 'solar-10-7b',
+ base_provider = 'Upstage',
+ best_provider = Airforce
+)
+
+solar_pro = Model(
+ name = 'solar-pro',
+ base_provider = 'Upstage',
+ best_provider = Upstage
)
-### Pi ###
+
+### Inflection ###
pi = Model(
name = 'pi',
- base_provider = 'inflection',
+ base_provider = 'Inflection',
best_provider = Pi
)
-### SambaNova ###
-samba_coe_v0_1 = Model(
- name = 'samba-coe-v0.1',
- base_provider = 'SambaNova',
- best_provider = Snova
+### DeepSeek ###
+deepseek = Model(
+ name = 'deepseek',
+ base_provider = 'DeepSeek',
+ best_provider = Airforce
)
-### Trong-Hieu Nguyen-Mau ###
-v1olet_merged_7b = Model(
- name = 'v1olet-merged-7b',
- base_provider = 'Trong-Hieu Nguyen-Mau',
- best_provider = Snova
+### WizardLM ###
+wizardlm_2_7b = Model(
+ name = 'wizardlm-2-7b',
+ base_provider = 'WizardLM',
+ best_provider = DeepInfraChat
)
-### Macadeliccc ###
-westlake_7b_v2 = Model(
- name = 'westlake-7b-v2',
- base_provider = 'Macadeliccc',
- best_provider = Snova
+wizardlm_2_8x22b = Model(
+ name = 'wizardlm-2-8x22b',
+ base_provider = 'WizardLM',
+ best_provider = IterListProvider([DeepInfraChat, Airforce])
)
-### CookinAI ###
-donutlm_v1 = Model(
- name = 'donutlm-v1',
- base_provider = 'CookinAI',
- best_provider = Snova
+### Together ###
+sh_n_7b = Model(
+ name = 'sh-n-7b',
+ base_provider = 'Together',
+ best_provider = Airforce
)
-### DeepSeek ###
-deepseek = Model(
- name = 'deepseek',
- base_provider = 'DeepSeek',
- best_provider = CodeNews
+
+### Yorickvp ###
+llava_13b = Model(
+ name = 'llava-13b',
+ base_provider = 'Yorickvp',
+ best_provider = ReplicateHome
+)
+
+
+### OpenBMB ###
+minicpm_llama_3_v2_5 = Model(
+ name = 'minicpm-llama-3-v2.5',
+ base_provider = 'OpenBMB',
+ best_provider = DeepInfraChat
+)
+
+
+### Lzlv ###
+lzlv_70b = Model(
+ name = 'lzlv-70b',
+ base_provider = 'Lzlv',
+ best_provider = DeepInfraChat
+)
+
+
+### OpenChat ###
+openchat_3_6_8b = Model(
+ name = 'openchat-3.6-8b',
+ base_provider = 'OpenChat',
+ best_provider = DeepInfraChat
+)
+
+
+### Phind ###
+phind_codellama_34b_v2 = Model(
+ name = 'phind-codellama-34b-v2',
+ base_provider = 'Phind',
+ best_provider = DeepInfraChat
+)
+
+
+### Cognitive Computations ###
+dolphin_2_9_1_llama_3_70b = Model(
+ name = 'dolphin-2.9.1-llama-3-70b',
+ base_provider = 'Cognitive Computations',
+ best_provider = DeepInfraChat
+)
+
+
+### x.ai ###
+grok_2 = Model(
+ name = 'grok-2',
+ base_provider = 'x.ai',
+ best_provider = Liaobots
+)
+
+grok_2_mini = Model(
+ name = 'grok-2-mini',
+ base_provider = 'x.ai',
+ best_provider = Liaobots
+)
+
+# Perplexity AI
+sonar_online = Model(
+ name = 'sonar-online',
+ base_provider = 'Perplexity AI',
+ best_provider = IterListProvider([ChatHub, PerplexityLabs])
+)
+
+sonar_chat = Model(
+ name = 'sonar-chat',
+ base_provider = 'Perplexity AI',
+ best_provider = PerplexityLabs
)
@@ -428,7 +634,7 @@ deepseek = Model(
sdxl = Model(
name = 'sdxl',
base_provider = 'Stability AI',
- best_provider = IterListProvider([ReplicateHome, DeepInfraImage])
+ best_provider = IterListProvider([ReplicateHome, Nexra, DeepInfraImage])
)
@@ -439,10 +645,11 @@ sd_3 = Model(
)
+
### Playground ###
playground_v2_5 = Model(
name = 'playground-v2.5',
- base_provider = 'Stability AI',
+ base_provider = 'Playground AI',
best_provider = IterListProvider([ReplicateHome])
)
@@ -451,43 +658,78 @@ playground_v2_5 = Model(
flux = Model(
name = 'flux',
base_provider = 'Flux AI',
- best_provider = IterListProvider([FluxAirforce])
+ best_provider = IterListProvider([Airforce, Blackbox])
)
flux_realism = Model(
name = 'flux-realism',
base_provider = 'Flux AI',
- best_provider = IterListProvider([FluxAirforce])
+ best_provider = IterListProvider([Airforce])
)
flux_anime = Model(
name = 'flux-anime',
base_provider = 'Flux AI',
- best_provider = IterListProvider([FluxAirforce])
+ best_provider = IterListProvider([Airforce])
)
flux_3d = Model(
name = 'flux-3d',
base_provider = 'Flux AI',
- best_provider = IterListProvider([FluxAirforce])
+ best_provider = IterListProvider([Airforce])
)
flux_disney = Model(
name = 'flux-disney',
base_provider = 'Flux AI',
- best_provider = IterListProvider([FluxAirforce])
+ best_provider = IterListProvider([Airforce])
+
+)
+
+flux_pixel = Model(
+ name = 'flux-pixel',
+ base_provider = 'Flux AI',
+ best_provider = IterListProvider([Airforce])
+
+)
+
+flux_4o = Model(
+ name = 'flux-4o',
+ base_provider = 'Flux AI',
+ best_provider = IterListProvider([Airforce])
)
+flux_schnell = Model(
+ name = 'flux-schnell',
+ base_provider = 'Flux AI',
+ best_provider = IterListProvider([ReplicateHome])
+
+)
+
+
### ###
+dalle_2 = Model(
+ name = 'dalle-2',
+ base_provider = '',
+ best_provider = IterListProvider([Nexra])
+
+)
+dalle_3 = Model(
+ name = 'dalle-3',
+ base_provider = '',
+ best_provider = IterListProvider([Airforce])
+
+)
+
dalle = Model(
name = 'dalle',
base_provider = '',
- best_provider = IterListProvider([Nexra])
+ best_provider = IterListProvider([Nexra, dalle_2.best_provider, dalle_3.best_provider])
)
@@ -498,6 +740,7 @@ dalle_mini = Model(
)
+### Other ###
emi = Model(
name = 'emi',
base_provider = '',
@@ -505,6 +748,20 @@ emi = Model(
)
+any_dark = Model(
+ name = 'any-dark',
+ base_provider = '',
+ best_provider = IterListProvider([Airforce])
+
+)
+
+prodia = Model(
+ name = 'prodia',
+ base_provider = '',
+ best_provider = IterListProvider([Nexra])
+
+)
+
class ModelUtils:
"""
Utility class for mapping string identifiers to Model instances.
@@ -526,37 +783,47 @@ class ModelUtils:
'gpt-3.5-turbo': gpt_35_turbo,
# gpt-4
-'gpt-4o' : gpt_4o,
-'gpt-4o-mini' : gpt_4o_mini,
-'gpt-4' : gpt_4,
-'gpt-4-turbo' : gpt_4_turbo,
-
+'gpt-4o': gpt_4o,
+'gpt-4o-mini': gpt_4o_mini,
+'gpt-4': gpt_4,
+'gpt-4-turbo': gpt_4_turbo,
+
### Meta ###
"meta-ai": meta,
+# llama-2
+'llama-2-13b': llama_2_13b,
+
# llama-3
+'llama-3': llama_3,
'llama-3-8b': llama_3_8b,
'llama-3-70b': llama_3_70b,
# llama-3.1
+'llama-3.1': llama_3_1,
'llama-3.1-8b': llama_3_1_8b,
'llama-3.1-70b': llama_3_1_70b,
'llama-3.1-405b': llama_3_1_405b,
-
+
### Mistral ###
-'mixtral-8x7b': mixtral_8x7b,
'mistral-7b': mistral_7b,
-
-
-### 01-ai ###
-'yi-1.5-34b': yi_1_5_34b,
+'mixtral-8x7b': mixtral_8x7b,
+'mixtral-8x22b': mixtral_8x22b,
+'mistral-nemo': mistral_nemo,
+
+
+### NousResearch ###
+'mixtral-8x7b-dpo': mixtral_8x7b_dpo,
+'hermes-3': hermes_3,
+
+'yi-34b': yi_34b,
### Microsoft ###
-'phi-3-mini-4k': phi_3_mini_4k,
-
+'phi_3_medium-4k': phi_3_medium_4k,
+'phi-3.5-mini': phi_3_5_mini,
### Google ###
# gemini
@@ -566,24 +833,32 @@ class ModelUtils:
# gemma
'gemma-2b': gemma_2b,
+'gemma-2b-9b': gemma_2b_9b,
+'gemma-2b-27b': gemma_2b_27b,
+'gemma-2': gemma_2,
### Anthropic ###
'claude-2': claude_2,
'claude-2.0': claude_2_0,
'claude-2.1': claude_2_1,
-
+
+# claude 3
+'claude-3': claude_3,
'claude-3-opus': claude_3_opus,
'claude-3-sonnet': claude_3_sonnet,
-'claude-3-5-sonnet': claude_3_5_sonnet,
'claude-3-haiku': claude_3_haiku,
+
+# claude 3.5
+'claude-3.5': claude_3_5,
+'claude-3.5-sonnet': claude_3_5_sonnet,
### Reka AI ###
'reka-core': reka_core,
-### Blackbox ###
+### Blackbox AI ###
'blackbox': blackbox,
@@ -604,7 +879,11 @@ class ModelUtils:
### Qwen ###
+'qwen': qwen,
'qwen-1.5-14b': qwen_1_5_14b,
+'qwen-1.5-72b': qwen_1_5_72b,
+'qwen-1.5-110b': qwen_1_5_110b,
+'qwen-2-72b': qwen_2_72b,
'qwen-turbo': qwen_turbo,
@@ -620,29 +899,57 @@ class ModelUtils:
### Upstage ###
'solar-1-mini': solar_1_mini,
+'solar-10-7b': solar_10_7b,
+'solar-pro': solar_pro,
-### Pi ###
+### Inflection ###
'pi': pi,
+### DeepSeek ###
+'deepseek': deepseek,
-### SambaNova ###
-'samba-coe-v0.1': samba_coe_v0_1,
-
-
-### Trong-Hieu Nguyen-Mau ###
-'v1olet-merged-7b': v1olet_merged_7b,
+### Together ###
+'sh-n-7b': sh_n_7b,
+
+
+### Yorickvp ###
+'llava-13b': llava_13b,
-### Macadeliccc ###
-'westlake-7b-v2': westlake_7b_v2,
+### WizardLM ###
+'wizardlm-2-7b': wizardlm_2_7b,
+'wizardlm-2-8x22b': wizardlm_2_8x22b,
+
+
+### OpenBMB ###
+'minicpm-llama-3-v2.5': minicpm_llama_3_v2_5,
+
+
+### Lzlv ###
+'lzlv-70b': lzlv_70b,
+
+
+### OpenChat ###
+'openchat-3.6-8b': openchat_3_6_8b,
-### CookinAI ###
-'donutlm-v1': donutlm_v1,
-### DeepSeek ###
-'deepseek': deepseek,
+### Phind ###
+'phind-codellama-34b-v2': phind_codellama_34b_v2,
+
+
+### Cognitive Computations ###
+'dolphin-2.9.1-llama-3-70b': dolphin_2_9_1_llama_3_70b,
+
+
+### x.ai ###
+'grok-2': grok_2,
+'grok-2-mini': grok_2_mini,
+
+### Perplexity AI ###
+'sonar-online': sonar_online,
+'sonar-chat': sonar_chat,
@@ -665,12 +972,19 @@ class ModelUtils:
'flux-anime': flux_anime,
'flux-3d': flux_3d,
'flux-disney': flux_disney,
+'flux-pixel': flux_pixel,
+'flux-4o': flux_4o,
+'flux-schnell': flux_schnell,
### ###
'dalle': dalle,
+'dalle-2': dalle_2,
+'dalle-3': dalle_3,
'dalle-mini': dalle_mini,
'emi': emi,
+'any-dark': any_dark,
+'prodia': prodia,
}
_all_models = list(ModelUtils.convert.keys())