From f8e403a745c5caff31d7edb854dcba40eba3166d Mon Sep 17 00:00:00 2001 From: kqlio67 Date: Tue, 24 Sep 2024 13:23:53 +0300 Subject: Resolved merge conflicts --- g4f/Provider/AI365VIP.py | 4 +- g4f/Provider/Airforce.py | 121 +++++----- g4f/Provider/Aura.py | 4 +- g4f/Provider/Bixin123.py | 2 +- g4f/Provider/Blackbox.py | 61 +++-- g4f/Provider/ChatGot.py | 75 ------ g4f/Provider/ChatGpt.py | 10 +- g4f/Provider/ChatGptEs.py | 142 ++++++----- g4f/Provider/Chatgpt4o.py | 8 +- g4f/Provider/CodeNews.py | 94 -------- g4f/Provider/DDG.py | 163 ++++++------- g4f/Provider/DeepInfraChat.py | 142 +++++++++++ g4f/Provider/DeepInfraImage.py | 5 +- g4f/Provider/FlowGpt.py | 2 +- g4f/Provider/GptTalkRu.py | 59 ----- g4f/Provider/Liaobots.py | 72 ++++-- g4f/Provider/LiteIcoding.py | 29 ++- g4f/Provider/MagickPen.py | 155 +++++------- g4f/Provider/Pi.py | 1 + g4f/Provider/Snova.py | 131 ----------- g4f/Provider/TwitterBio.py | 103 -------- g4f/Provider/Upstage.py | 3 +- g4f/Provider/Vercel.py | 104 -------- g4f/Provider/__init__.py | 14 +- g4f/Provider/deprecated/Acytoo.py | 51 ---- g4f/Provider/deprecated/AiAsk.py | 46 ---- g4f/Provider/deprecated/AiService.py | 39 --- g4f/Provider/deprecated/Aibn.py | 46 ---- g4f/Provider/deprecated/Aichat.py | 64 ----- g4f/Provider/deprecated/Ails.py | 90 ------- g4f/Provider/deprecated/Aivvm.py | 73 ------ g4f/Provider/deprecated/Berlin.py | 78 ------ g4f/Provider/deprecated/ChatAnywhere.py | 54 ----- g4f/Provider/deprecated/ChatgptDuo.py | 47 ---- g4f/Provider/deprecated/CodeLinkAva.py | 52 ---- g4f/Provider/deprecated/Cromicle.py | 50 ---- g4f/Provider/deprecated/DfeHub.py | 62 ----- g4f/Provider/deprecated/EasyChat.py | 89 ------- g4f/Provider/deprecated/Equing.py | 71 ------ g4f/Provider/deprecated/FakeGpt.py | 91 ------- g4f/Provider/deprecated/FastGpt.py | 76 ------ g4f/Provider/deprecated/Forefront.py | 40 ---- g4f/Provider/deprecated/GPTalk.py | 87 ------- g4f/Provider/deprecated/GeekGpt.py | 73 ------ g4f/Provider/deprecated/GetGpt.py | 77 ------ g4f/Provider/deprecated/H2o.py | 89 ------- g4f/Provider/deprecated/Hashnode.py | 80 ------- g4f/Provider/deprecated/Lockchat.py | 54 ----- g4f/Provider/deprecated/Myshell.py | 165 ------------- g4f/Provider/deprecated/NoowAi.py | 66 ------ g4f/Provider/deprecated/Opchatgpts.py | 59 ----- g4f/Provider/deprecated/OpenAssistant.py | 88 ------- g4f/Provider/deprecated/Phind.py | 140 ----------- g4f/Provider/deprecated/V50.py | 61 ----- g4f/Provider/deprecated/Vercel.py | 392 ------------------------------- g4f/Provider/deprecated/Vitalentum.py | 55 ----- g4f/Provider/deprecated/VoiGpt.py | 91 ------- g4f/Provider/deprecated/Wewordle.py | 65 ----- g4f/Provider/deprecated/Wuguokai.py | 57 ----- g4f/Provider/deprecated/Ylokh.py | 58 ----- g4f/Provider/deprecated/Yqcloud.py | 61 ----- g4f/Provider/deprecated/__init__.py | 35 --- g4f/Provider/needs_auth/Gemini.py | 3 +- g4f/Provider/needs_auth/OpenRouter.py | 4 +- g4f/Provider/needs_auth/Openai.py | 2 +- g4f/Provider/needs_auth/OpenaiChat.py | 6 +- g4f/Provider/needs_auth/PerplexityApi.py | 3 +- g4f/Provider/needs_auth/__init__.py | 4 +- g4f/Provider/selenium/Bard.py | 80 ------- g4f/Provider/selenium/MyShell.py | 4 +- g4f/Provider/selenium/PerplexityAi.py | 4 +- g4f/Provider/selenium/TalkAi.py | 4 +- g4f/Provider/selenium/__init__.py | 1 - g4f/Provider/unfinished/AiChatting.py | 66 ------ g4f/Provider/unfinished/ChatAiGpt.py | 68 ------ g4f/Provider/unfinished/Komo.py | 44 ---- g4f/Provider/unfinished/MikuChat.py | 97 -------- g4f/Provider/unfinished/__init__.py | 4 - g4f/gui/client/static/css/style.css | 3 +- g4f/models.py | 386 +++++++++++++++++++++--------- 80 files changed, 842 insertions(+), 4417 deletions(-) delete mode 100644 g4f/Provider/ChatGot.py delete mode 100644 g4f/Provider/CodeNews.py create mode 100644 g4f/Provider/DeepInfraChat.py delete mode 100644 g4f/Provider/GptTalkRu.py delete mode 100644 g4f/Provider/Snova.py delete mode 100644 g4f/Provider/TwitterBio.py delete mode 100644 g4f/Provider/Vercel.py delete mode 100644 g4f/Provider/deprecated/Acytoo.py delete mode 100644 g4f/Provider/deprecated/AiAsk.py delete mode 100644 g4f/Provider/deprecated/AiService.py delete mode 100644 g4f/Provider/deprecated/Aibn.py delete mode 100644 g4f/Provider/deprecated/Aichat.py delete mode 100644 g4f/Provider/deprecated/Ails.py delete mode 100644 g4f/Provider/deprecated/Aivvm.py delete mode 100644 g4f/Provider/deprecated/Berlin.py delete mode 100644 g4f/Provider/deprecated/ChatAnywhere.py delete mode 100644 g4f/Provider/deprecated/ChatgptDuo.py delete mode 100644 g4f/Provider/deprecated/CodeLinkAva.py delete mode 100644 g4f/Provider/deprecated/Cromicle.py delete mode 100644 g4f/Provider/deprecated/DfeHub.py delete mode 100644 g4f/Provider/deprecated/EasyChat.py delete mode 100644 g4f/Provider/deprecated/Equing.py delete mode 100644 g4f/Provider/deprecated/FakeGpt.py delete mode 100644 g4f/Provider/deprecated/FastGpt.py delete mode 100644 g4f/Provider/deprecated/Forefront.py delete mode 100644 g4f/Provider/deprecated/GPTalk.py delete mode 100644 g4f/Provider/deprecated/GeekGpt.py delete mode 100644 g4f/Provider/deprecated/GetGpt.py delete mode 100644 g4f/Provider/deprecated/H2o.py delete mode 100644 g4f/Provider/deprecated/Hashnode.py delete mode 100644 g4f/Provider/deprecated/Lockchat.py delete mode 100644 g4f/Provider/deprecated/Myshell.py delete mode 100644 g4f/Provider/deprecated/NoowAi.py delete mode 100644 g4f/Provider/deprecated/Opchatgpts.py delete mode 100644 g4f/Provider/deprecated/OpenAssistant.py delete mode 100644 g4f/Provider/deprecated/Phind.py delete mode 100644 g4f/Provider/deprecated/V50.py delete mode 100644 g4f/Provider/deprecated/Vercel.py delete mode 100644 g4f/Provider/deprecated/Vitalentum.py delete mode 100644 g4f/Provider/deprecated/VoiGpt.py delete mode 100644 g4f/Provider/deprecated/Wewordle.py delete mode 100644 g4f/Provider/deprecated/Wuguokai.py delete mode 100644 g4f/Provider/deprecated/Ylokh.py delete mode 100644 g4f/Provider/deprecated/Yqcloud.py delete mode 100644 g4f/Provider/deprecated/__init__.py delete mode 100644 g4f/Provider/selenium/Bard.py delete mode 100644 g4f/Provider/unfinished/AiChatting.py delete mode 100644 g4f/Provider/unfinished/ChatAiGpt.py delete mode 100644 g4f/Provider/unfinished/Komo.py delete mode 100644 g4f/Provider/unfinished/MikuChat.py delete mode 100644 g4f/Provider/unfinished/__init__.py (limited to 'g4f') 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/Airforce.py b/g4f/Provider/Airforce.py index 88896096..51f8ba55 100644 --- a/g4f/Provider/Airforce.py +++ b/g4f/Provider/Airforce.py @@ -1,20 +1,17 @@ from __future__ import annotations from aiohttp import ClientSession, ClientResponseError -from urllib.parse import urlencode import json -import io -import asyncio - from ..typing import AsyncResult, Messages from .base_provider import AsyncGeneratorProvider, ProviderModelMixin -from ..image import ImageResponse, is_accepted_format +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/v1/imagine2" + image_api_endpoint = "https://api.airforce/imagine2" working = True supports_gpt_35_turbo = True supports_gpt_4 = True @@ -25,53 +22,38 @@ class Airforce(AsyncGeneratorProvider, ProviderModelMixin): 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', @@ -85,10 +67,10 @@ class Airforce(AsyncGeneratorProvider, ProviderModelMixin): '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', @@ -96,7 +78,9 @@ class Airforce(AsyncGeneratorProvider, ProviderModelMixin): 'flux-3d', 'flux-disney', 'flux-pixel', + 'flux-4o', 'any-dark', + 'dall-e-3', ] models = [ @@ -106,61 +90,47 @@ class Airforce(AsyncGeneratorProvider, ProviderModelMixin): 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-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 @@ -178,16 +148,20 @@ class Airforce(AsyncGeneratorProvider, ProviderModelMixin): "accept-language": "en-US,en;q=0.9", "content-type": "application/json", "origin": "https://api.airforce", - "sec-ch-ua": '"Chromium";v="128", "Not(A:Brand";v="24"', + "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", - "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.image_models: async for item in cls.generate_image(model, messages, headers, proxy, **kwargs): yield item @@ -197,31 +171,44 @@ class Airforce(AsyncGeneratorProvider, ProviderModelMixin): @classmethod async def generate_text(cls, model: str, messages: Messages, headers: dict, proxy: str, **kwargs) -> AsyncResult: - async with ClientSession(headers=headers) as session: + async with ClientSession() as session: data = { - "messages": [{"role": "user", "content": format_prompt(messages)}], + "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 } - - async with session.post(cls.text_api_endpoint, json=data, proxy=proxy) as response: - response.raise_for_status() - async for line in response.content: - if line: - line = line.decode('utf-8').strip() - if line.startswith("data: "): - try: - data = json.loads(line[6:]) - if 'choices' in data and len(data['choices']) > 0: - delta = data['choices'][0].get('delta', {}) - if 'content' in delta: - yield delta['content'] - except json.JSONDecodeError: - continue - elif line == "data: [DONE]": - break + + 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: @@ -246,10 +233,10 @@ class Airforce(AsyncGeneratorProvider, ProviderModelMixin): else: try: text = content.decode('utf-8', errors='ignore') - yield f"Error: {text}" + raise ResponseStatusError("Image generation failed", response.status, text) except Exception as decode_error: - yield f"Error: Unable to decode response - {str(decode_error)}" + raise ResponseStatusError("Decoding error", 500, str(decode_error)) except ClientResponseError as e: - yield f"Error: HTTP {e.status}: {e.message}" + raise ResponseStatusError(f"HTTP {e.status}", e.status, e.message) except Exception as e: - yield f"Unexpected error: {str(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 39422c93..081064f9 100644 --- a/g4f/Provider/Bixin123.py +++ b/g4f/Provider/Bixin123.py @@ -15,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", diff --git a/g4f/Provider/Blackbox.py b/g4f/Provider/Blackbox.py index e607a43c..40696c82 100644 --- a/g4f/Provider/Blackbox.py +++ b/g4f/Provider/Blackbox.py @@ -1,7 +1,6 @@ from __future__ import annotations import re -import json import random import string from aiohttp import ClientSession @@ -25,22 +24,44 @@ class Blackbox(AsyncGeneratorProvider, ProviderModelMixin): "llama-3.1-8b", 'llama-3.1-70b', 'llama-3.1-405b', - 'ImageGenerationLV45LJp' + '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", + } + + agentMode = { + 'ImageGenerationLV45LJp': {'mode': True, 'id': "ImageGenerationLV45LJp", 'name': "Image Generation"}, + } - model_config = { + 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"}, - 'ImageGenerationLV45LJp': {'mode': True, 'id': "ImageGenerationLV45LJp", 'name': "Image Generation"}, + } + + 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: @@ -74,6 +95,11 @@ class Blackbox(AsyncGeneratorProvider, ProviderModelMixin): "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: if image is not None: @@ -92,21 +118,27 @@ class Blackbox(AsyncGeneratorProvider, ProviderModelMixin): "codeModelMode": True, "agentMode": {}, "trendingAgentMode": {}, + "userSelectedModel": None, "isMicMode": False, - "maxTokens": None, + "maxTokens": 99999999, + "playgroundTopP": 0.9, + "playgroundTemperature": 0.5, "isChromeExt": False, "githubToken": None, "clickedAnswer2": False, "clickedAnswer3": False, "clickedForceWebSearch": False, "visitFromDelta": False, - "mobileClient": False + "mobileClient": False, + "webSearchMode": False, } - if model == 'ImageGenerationLV45LJp': - data["agentMode"] = cls.model_config[model] - else: - data["trendingAgentMode"] = cls.model_config[model] + 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() @@ -119,9 +151,10 @@ class Blackbox(AsyncGeneratorProvider, ProviderModelMixin): else: raise Exception("Image URL not found in the response") else: - async for chunk in response.content: + async for chunk in response.content.iter_any(): if chunk: decoded_chunk = chunk.decode() - if decoded_chunk.startswith('$@$v=undefined-rv1$@$'): - decoded_chunk = decoded_chunk[len('$@$v=undefined-rv1$@$'):] - yield decoded_chunk + # Видаляємо префікс $@$v=v1.10-rv1$@$ та інші подібні + decoded_chunk = re.sub(r'\$@\$v=[^$]+\$@\$', '', decoded_chunk) + if decoded_chunk.strip(): # Перевіряємо, чи залишився якийсь текст після видалення префікса + yield decoded_chunk diff --git a/g4f/Provider/ChatGot.py b/g4f/Provider/ChatGot.py deleted file mode 100644 index 55e8d0b6..00000000 --- a/g4f/Provider/ChatGot.py +++ /dev/null @@ -1,75 +0,0 @@ -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 ChatGot(AsyncGeneratorProvider, ProviderModelMixin): - url = "https://www.chatgot.one/" - working = 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/ChatGpt.py b/g4f/Provider/ChatGpt.py index 878fb424..fc34fc2b 100644 --- a/g4f/Provider/ChatGpt.py +++ b/g4f/Provider/ChatGpt.py @@ -76,7 +76,13 @@ class ChatGpt(AbstractProvider, ProviderModelMixin): 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( @@ -197,4 +203,4 @@ class ChatGpt(AbstractProvider, ProviderModelMixin): yield tokens.replace(replace, '') - replace = tokens \ No newline at end of file + replace = tokens diff --git a/g4f/Provider/ChatGptEs.py b/g4f/Provider/ChatGptEs.py index d94ba59e..0e7062e5 100644 --- a/g4f/Provider/ChatGptEs.py +++ b/g4f/Provider/ChatGptEs.py @@ -1,95 +1,85 @@ from __future__ import annotations -from ..typing import Messages, CreateResult -from ..providers.base_provider import AbstractProvider, ProviderModelMixin +from aiohttp import ClientSession +import os +import json +import re -import requests, os, re, json +from ..typing import AsyncResult, Messages +from .base_provider import AsyncGeneratorProvider, ProviderModelMixin +from .helper import format_prompt -class ChatGptEs(AbstractProvider, ProviderModelMixin): - label = "ChatGptEs" +class ChatGptEs(AsyncGeneratorProvider, ProviderModelMixin): + url = "https://chatgpt.es" + api_endpoint = "https://chatgpt.es/wp-admin/admin-ajax.php" working = True - supports_message_history = True + supports_gpt_4 = True + supports_stream = True supports_system_message = True - supports_stream = False + 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 - def create_completion( + async def create_async_generator( cls, model: str, messages: Messages, - stream: bool, + proxy: str = None, **kwargs - ) -> CreateResult: + ) -> AsyncResult: + model = cls.get_model(model) - if model not in [ - 'gpt-4o', - 'gpt-4o-mini', - 'chatgpt-4o-latest' - ]: - raise ValueError(f"Unsupported model: {model}") - headers = { - 'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7', - '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', - 'priority': 'u=0, i', - 'referer': 'https://www.google.com/', - 'sec-ch-ua': '"Google Chrome";v="129", "Not=A?Brand";v="8", "Chromium";v="129"', - 'sec-ch-ua-mobile': '?0', - 'sec-ch-ua-platform': '"macOS"', - 'sec-fetch-dest': 'document', - 'sec-fetch-mode': 'navigate', - 'sec-fetch-site': 'cross-site', - 'sec-fetch-user': '?1', - 'upgrade-insecure-requests': '1', - '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', + "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", } - response = requests.get('https://chatgpt.es/', headers=headers) - nonce_ = re.findall(r'data-nonce="(.+?)"', response.text)[0] - post_id = re.findall(r'data-post-id="(.+?)"', response.text)[0] + 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] - headers = { - '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', - 'origin': 'https://chatgpt.es', - 'pragma': 'no-cache', - 'priority': 'u=1, i', - 'referer': 'https://chatgpt.es/', - 'sec-ch-ua': '"Google Chrome";v="129", "Not=A?Brand";v="8", "Chromium";v="129"', - '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/129.0.0.0 Safari/537.36', - } - - conversation_history = [ - "Human: stricly 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']}") + conversation_history = [ + "Human: strictly respond in the same language as my prompt, preferably English" + ] - payload = { - '_wpnonce': nonce_, - 'post_id': post_id, - 'url': 'https://chatgpt.es', - '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) - } + for message in messages[:-1]: + if message['role'] == "user": + conversation_history.append(f"Human: {message['content']}") + else: + conversation_history.append(f"AI: {message['content']}") - response = requests.post('https://chatgpt.es/wp-admin/admin-ajax.php', - headers=headers, data=payload).json() - - return (response['data']) \ No newline at end of file + 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/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..fa6dd2fe --- /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", + "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/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/Liaobots.py b/g4f/Provider/Liaobots.py index 8a9f46b1..598da5ea 100644 --- a/g4f/Provider/Liaobots.py +++ b/g4f/Provider/Liaobots.py @@ -36,6 +36,24 @@ models = { "tokenLimit": 7800, "context": "8K", }, + "o1-preview": { + "id": "o1-preview", + "name": "o1-preview", + "model": "o1", + "provider": "OpenAI", + "maxLength": 400000, + "tokenLimit": 100000, + "context": "128K", + }, + "o1-mini": { + "id": "o1-mini", + "name": "o1-mini", + "model": "o1", + "provider": "OpenAI", + "maxLength": 400000, + "tokenLimit": 100000, + "context": "128K", + }, "gpt-4-turbo-2024-04-09": { "id": "gpt-4-turbo-2024-04-09", "name": "GPT-4-Turbo", @@ -54,14 +72,23 @@ models = { "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", @@ -126,17 +153,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-exp-0827": { + "id": "gemini-1.5-flash-exp-0827", "name": "Gemini-1.5-Flash-1M", "model": "Gemini", "provider": "Google", @@ -144,8 +162,8 @@ models = { "tokenLimit": 1000000, "context": "1024K", }, - "gemini-1.5-pro-latest": { - "id": "gemini-1.5-pro-latest", + "gemini-1.5-pro-exp-0827": { + "id": "gemini-1.5-pro-exp-0827", "name": "Gemini-1.5-Pro-1M", "model": "Gemini", "provider": "Google", @@ -162,12 +180,15 @@ 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", + + "o1": "o1-preview", + "gpt-4-turbo": "gpt-4-turbo-2024-04-09", "gpt-4o": "gpt-4o-2024-08-06", "gpt-4": "gpt-4-0613", @@ -176,13 +197,12 @@ class Liaobots(AsyncGeneratorProvider, ProviderModelMixin): "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-exp-0827", + "gemini-pro": "gemini-1.5-pro-exp-0827", } _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/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/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/Snova.py b/g4f/Provider/Snova.py deleted file mode 100644 index 53d8f0bd..00000000 --- a/g4f/Provider/Snova.py +++ /dev/null @@ -1,131 +0,0 @@ -from __future__ import annotations - -import json -from typing import AsyncGenerator - -from aiohttp import ClientSession - -from ..typing import AsyncResult, Messages -from .base_provider import AsyncGeneratorProvider, ProviderModelMixin -from .helper import format_prompt - - -class Snova(AsyncGeneratorProvider, ProviderModelMixin): - url = "https://fast.snova.ai" - api_endpoint = "https://fast.snova.ai/api/completion" - working = True - supports_stream = True - supports_system_message = True - supports_message_history = True - - default_model = 'Meta-Llama-3.1-8B-Instruct' - models = [ - 'Meta-Llama-3.1-8B-Instruct', - 'Meta-Llama-3.1-70B-Instruct', - 'Meta-Llama-3.1-405B-Instruct', - 'Samba-CoE', - 'ignos/Mistral-T5-7B-v1', # Error with the answer - 'v1olet/v1olet_merged_dpo_7B', - 'macadeliccc/WestLake-7B-v2-laser-truthy-dpo', - ] - - model_aliases = { - "llama-3.1-8b": "Meta-Llama-3.1-8B-Instruct", - "llama-3.1-70b": "Meta-Llama-3.1-70B-Instruct", - "llama-3.1-405b": "Meta-Llama-3.1-405B-Instruct", - - "mistral-7b": "ignos/Mistral-T5-7B-v1", - - "samba-coe-v0.1": "Samba-CoE", - "v1olet-merged-7b": "v1olet/v1olet_merged_dpo_7B", - "westlake-7b-v2": "macadeliccc/WestLake-7B-v2-laser-truthy-dpo", - } - - @classmethod - def get_model(cls, model: str) -> str: - if model in cls.models: - return model - elif model in cls.model_aliases: - return cls.model_aliases[model] - else: - return cls.default_model - - @classmethod - async def create_async_generator( - cls, - model: str, - messages: Messages, - proxy: str = None, - **kwargs - ) -> AsyncGenerator[str, None]: - model = cls.get_model(model) - - headers = { - "accept": "text/event-stream", - "accept-language": "en-US,en;q=0.9", - "cache-control": "no-cache", - "content-type": "application/json", - "origin": cls.url, - "pragma": "no-cache", - "priority": "u=1, i", - "referer": f"{cls.url}/", - "sec-ch-ua": '"Chromium";v="127", "Not)A;Brand";v="99"', - "sec-ch-ua-mobile": "?0", - "sec-ch-ua-platform": '"Linux"', - "sec-fetch-dest": "empty", - "sec-fetch-mode": "cors", - "sec-fetch-site": "same-origin", - "user-agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36" - } - async with ClientSession(headers=headers) as session: - data = { - "body": { - "messages": [ - { - "role": "system", - "content": "You are a helpful assistant." - }, - { - "role": "user", - "content": format_prompt(messages), - "id": "1-id", - "ref": "1-ref", - "revision": 1, - "draft": False, - "status": "done", - "enableRealTimeChat": False, - "meta": None - } - ], - "max_tokens": 1000, - "stop": ["<|eot_id|>"], - "stream": True, - "stream_options": {"include_usage": True}, - "model": model - }, - "env_type": "tp16" - } - async with session.post(cls.api_endpoint, json=data, proxy=proxy) as response: - response.raise_for_status() - full_response = "" - async for line in response.content: - line = line.decode().strip() - if line.startswith("data: "): - data = line[6:] - if data == "[DONE]": - break - try: - json_data = json.loads(data) - choices = json_data.get("choices", []) - if choices: - delta = choices[0].get("delta", {}) - content = delta.get("content", "") - full_response += content - except json.JSONDecodeError: - continue - except Exception as e: - print(f"Error processing chunk: {e}") - print(f"Problematic data: {data}") - continue - - yield full_response.strip() diff --git a/g4f/Provider/TwitterBio.py b/g4f/Provider/TwitterBio.py deleted file mode 100644 index c143e4ff..00000000 --- a/g4f/Provider/TwitterBio.py +++ /dev/null @@ -1,103 +0,0 @@ -from __future__ import annotations - -import json -import re -from aiohttp import ClientSession - -from ..typing import AsyncResult, Messages -from .base_provider import AsyncGeneratorProvider, ProviderModelMixin -from .helper import format_prompt - -class TwitterBio(AsyncGeneratorProvider, ProviderModelMixin): - url = "https://www.twitterbio.io" - api_endpoint_mistral = "https://www.twitterbio.io/api/mistral" - api_endpoint_openai = "https://www.twitterbio.io/api/openai" - working = True - supports_gpt_35_turbo = True - - default_model = 'gpt-3.5-turbo' - models = [ - 'mistralai/Mixtral-8x7B-Instruct-v0.1', - 'gpt-3.5-turbo', - ] - - model_aliases = { - "mixtral-8x7b": "mistralai/Mixtral-8x7B-Instruct-v0.1", - } - - @classmethod - def get_model(cls, model: str) -> str: - if model in cls.models: - return model - return cls.default_model - - @staticmethod - def format_text(text: str) -> str: - text = re.sub(r'\s+', ' ', text.strip()) - text = re.sub(r'\s+([,.!?])', r'\1', text) - return text - - @classmethod - async def create_async_generator( - cls, - model: str, - messages: Messages, - proxy: str = None, - **kwargs - ) -> AsyncResult: - model = cls.get_model(model) - - headers = { - "accept": "*/*", - "accept-language": "en-US,en;q=0.9", - "cache-control": "no-cache", - "content-type": "application/json", - "origin": cls.url, - "pragma": "no-cache", - "priority": "u=1, i", - "referer": f"{cls.url}/", - "sec-ch-ua": '"Chromium";v="127", "Not)A;Brand";v="99"', - "sec-ch-ua-mobile": "?0", - "sec-ch-ua-platform": '"Linux"', - "sec-fetch-dest": "empty", - "sec-fetch-mode": "cors", - "sec-fetch-site": "same-origin", - "user-agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36" - } - async with ClientSession(headers=headers) as session: - prompt = format_prompt(messages) - data = { - "prompt": f'{prompt}.' - } - - if model == 'mistralai/Mixtral-8x7B-Instruct-v0.1': - api_endpoint = cls.api_endpoint_mistral - elif model == 'gpt-3.5-turbo': - api_endpoint = cls.api_endpoint_openai - else: - raise ValueError(f"Unsupported model: {model}") - - async with session.post(api_endpoint, json=data, proxy=proxy) as response: - response.raise_for_status() - buffer = "" - async for line in response.content: - line = line.decode('utf-8').strip() - if line.startswith('data: '): - try: - json_data = json.loads(line[6:]) - if model == 'mistralai/Mixtral-8x7B-Instruct-v0.1': - if 'choices' in json_data and len(json_data['choices']) > 0: - text = json_data['choices'][0].get('text', '') - if text: - buffer += text - elif model == 'gpt-3.5-turbo': - text = json_data.get('text', '') - if text: - buffer += text - except json.JSONDecodeError: - continue - elif line == 'data: [DONE]': - break - - if buffer: - yield cls.format_text(buffer) diff --git a/g4f/Provider/Upstage.py b/g4f/Provider/Upstage.py index e61a5af2..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 `${this}`}; - 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 a13bcb1f..30148f27 100644 --- a/g4f/Provider/__init__.py +++ b/g4f/Provider/__init__.py @@ -5,7 +5,6 @@ from ..providers.retry_provider import RetryProvider, IterListProvider from ..providers.base_provider import AsyncProvider, AsyncGeneratorProvider from ..providers.create_images import CreateImagesProvider -from .deprecated import * from .selenium import * from .needs_auth import * @@ -20,13 +19,14 @@ from .BingCreateImages import BingCreateImages from .Binjie import Binjie from .Bixin123 import Bixin123 from .Blackbox import Blackbox -from .ChatGot import ChatGot +from .ChatGpt import ChatGpt from .Chatgpt4Online import Chatgpt4Online from .Chatgpt4o import Chatgpt4o +from .ChatGptEs import ChatGptEs from .ChatgptFree import ChatgptFree -from .CodeNews import CodeNews from .DDG import DDG from .DeepInfra import DeepInfra +from .DeepInfraChat import DeepInfraChat from .DeepInfraImage import DeepInfraImage from .FlowGpt import FlowGpt from .Free2GPT import Free2GPT @@ -35,7 +35,6 @@ from .FreeGpt import FreeGpt from .FreeNetfly import FreeNetfly from .GeminiPro import GeminiPro from .GigaChat import GigaChat -from .GptTalkRu import GptTalkRu from .HuggingChat import HuggingChat from .HuggingFace import HuggingFace from .Koala import Koala @@ -44,7 +43,7 @@ from .LiteIcoding import LiteIcoding 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 @@ -52,17 +51,12 @@ 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 .TeachAnything import TeachAnything -from .TwitterBio import TwitterBio from .Upstage import Upstage -from .Vercel import Vercel from .WhiteRabbitNeo import WhiteRabbitNeo from .You import You -from .ChatGpt import ChatGpt -from .ChatGptEs import ChatGptEs import sys diff --git a/g4f/Provider/deprecated/Acytoo.py b/g4f/Provider/deprecated/Acytoo.py deleted file mode 100644 index f75821ce..00000000 --- a/g4f/Provider/deprecated/Acytoo.py +++ /dev/null @@ -1,51 +0,0 @@ -from __future__ import annotations - -from aiohttp import ClientSession - -from ...typing import AsyncResult, Messages -from ..base_provider import AsyncGeneratorProvider - - -class Acytoo(AsyncGeneratorProvider): - url = 'https://chat.acytoo.com' - working = False - supports_message_history = True - supports_gpt_35_turbo = True - - @classmethod - async def create_async_generator( - cls, - model: str, - messages: Messages, - proxy: str = None, - **kwargs - ) -> AsyncResult: - async with ClientSession( - headers=_create_header() - ) as session: - async with session.post( - f'{cls.url}/api/completions', - proxy=proxy, - json=_create_payload(messages, **kwargs) - ) as response: - response.raise_for_status() - async for stream in response.content.iter_any(): - if stream: - yield stream.decode() - - -def _create_header(): - return { - 'accept': '*/*', - 'content-type': 'application/json', - } - - -def _create_payload(messages: Messages, temperature: float = 0.5, **kwargs): - return { - 'key' : '', - 'model' : 'gpt-3.5-turbo', - 'messages' : messages, - 'temperature' : temperature, - 'password' : '' - } \ No newline at end of file diff --git a/g4f/Provider/deprecated/AiAsk.py b/g4f/Provider/deprecated/AiAsk.py deleted file mode 100644 index 6ea5f3e0..00000000 --- a/g4f/Provider/deprecated/AiAsk.py +++ /dev/null @@ -1,46 +0,0 @@ -from __future__ import annotations - -from aiohttp import ClientSession -from ...typing import AsyncResult, Messages -from ..base_provider import AsyncGeneratorProvider - -class AiAsk(AsyncGeneratorProvider): - url = "https://e.aiask.me" - supports_message_history = True - supports_gpt_35_turbo = True - working = False - - @classmethod - async def create_async_generator( - cls, - model: str, - messages: Messages, - proxy: str = None, - **kwargs - ) -> AsyncResult: - headers = { - "accept": "application/json, text/plain, */*", - "origin": cls.url, - "referer": f"{cls.url}/chat", - } - async with ClientSession(headers=headers) as session: - data = { - "continuous": True, - "id": "fRMSQtuHl91A4De9cCvKD", - "list": messages, - "models": "0", - "prompt": "", - "temperature": kwargs.get("temperature", 0.5), - "title": "", - } - buffer = "" - rate_limit = "您的免费额度不够使用这个模型啦,请点击右上角登录继续使用!" - async with session.post(f"{cls.url}/v1/chat/gpt/", json=data, proxy=proxy) as response: - response.raise_for_status() - async for chunk in response.content.iter_any(): - buffer += chunk.decode() - if not rate_limit.startswith(buffer): - yield buffer - buffer = "" - elif buffer == rate_limit: - raise RuntimeError("Rate limit reached") \ No newline at end of file diff --git a/g4f/Provider/deprecated/AiService.py b/g4f/Provider/deprecated/AiService.py deleted file mode 100644 index acd7f5ea..00000000 --- a/g4f/Provider/deprecated/AiService.py +++ /dev/null @@ -1,39 +0,0 @@ -from __future__ import annotations - -import requests - -from ...typing import Any, CreateResult, Messages -from ..base_provider import AbstractProvider - - -class AiService(AbstractProvider): - url = "https://aiservice.vercel.app/" - working = False - supports_gpt_35_turbo = True - - @staticmethod - def create_completion( - model: str, - messages: Messages, - stream: bool, - **kwargs: Any, - ) -> CreateResult: - base = ( - "\n".join( - f"{message['role']}: {message['content']}" for message in messages - ) - + "\nassistant: " - ) - headers = { - "accept": "*/*", - "content-type": "text/plain;charset=UTF-8", - "sec-fetch-dest": "empty", - "sec-fetch-mode": "cors", - "sec-fetch-site": "same-origin", - "Referer": "https://aiservice.vercel.app/chat", - } - data = {"input": base} - url = "https://aiservice.vercel.app/api/chat/answer" - response = requests.post(url, headers=headers, json=data) - response.raise_for_status() - yield response.json()["data"] diff --git a/g4f/Provider/deprecated/Aibn.py b/g4f/Provider/deprecated/Aibn.py deleted file mode 100644 index 0bbfb436..00000000 --- a/g4f/Provider/deprecated/Aibn.py +++ /dev/null @@ -1,46 +0,0 @@ -from __future__ import annotations - -import time -import hashlib - -from ...typing import AsyncResult, Messages -from ...requests import StreamSession -from ..base_provider import AsyncGeneratorProvider - - -class Aibn(AsyncGeneratorProvider): - url = "https://aibn.cc" - working = False - supports_message_history = True - supports_gpt_35_turbo = True - - @classmethod - async def create_async_generator( - cls, - model: str, - messages: Messages, - proxy: str = None, - timeout: int = 120, - **kwargs - ) -> AsyncResult: - async with StreamSession( - impersonate="chrome107", - proxies={"https": proxy}, - timeout=timeout - ) as session: - timestamp = int(time.time()) - data = { - "messages": messages, - "pass": None, - "sign": generate_signature(timestamp, messages[-1]["content"]), - "time": timestamp - } - async with session.post(f"{cls.url}/api/generate", json=data) as response: - response.raise_for_status() - async for chunk in response.iter_content(): - yield chunk.decode() - - -def generate_signature(timestamp: int, message: str, secret: str = "undefined"): - data = f"{timestamp}:{message}:{secret}" - return hashlib.sha256(data.encode()).hexdigest() \ No newline at end of file diff --git a/g4f/Provider/deprecated/Aichat.py b/g4f/Provider/deprecated/Aichat.py deleted file mode 100644 index 68c9c546..00000000 --- a/g4f/Provider/deprecated/Aichat.py +++ /dev/null @@ -1,64 +0,0 @@ -from __future__ import annotations - -from ...typing import Messages -from ..base_provider import AsyncProvider, format_prompt -from ..helper import get_cookies -from ...requests import StreamSession - -class Aichat(AsyncProvider): - url = "https://chat-gpt.org/chat" - working = False - supports_gpt_35_turbo = True - - @staticmethod - async def create_async( - model: str, - messages: Messages, - proxy: str = None, **kwargs) -> str: - - cookies = get_cookies('chat-gpt.org') if not kwargs.get('cookies') else kwargs.get('cookies') - if not cookies: - raise RuntimeError( - "g4f.provider.Aichat requires cookies, [refresh https://chat-gpt.org on chrome]" - ) - - headers = { - 'authority': 'chat-gpt.org', - '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', - 'content-type': 'application/json', - 'origin': 'https://chat-gpt.org', - 'referer': 'https://chat-gpt.org/chat', - 'sec-ch-ua': '"Chromium";v="118", "Google Chrome";v="118", "Not=A?Brand";v="99"', - '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/118.0.0.0 Safari/537.36', - } - - async with StreamSession(headers=headers, - cookies=cookies, - timeout=6, - proxies={"https": proxy} if proxy else None, - impersonate="chrome110", verify=False) as session: - - json_data = { - "message": format_prompt(messages), - "temperature": kwargs.get('temperature', 0.5), - "presence_penalty": 0, - "top_p": kwargs.get('top_p', 1), - "frequency_penalty": 0, - } - - async with session.post("https://chat-gpt.org/api/text", - json=json_data) as response: - - response.raise_for_status() - result = await response.json() - - if not result['response']: - raise Exception(f"Error Response: {result}") - - return result["message"] diff --git a/g4f/Provider/deprecated/Ails.py b/g4f/Provider/deprecated/Ails.py deleted file mode 100644 index e87ceb32..00000000 --- a/g4f/Provider/deprecated/Ails.py +++ /dev/null @@ -1,90 +0,0 @@ -from __future__ import annotations - -import hashlib -import time -import uuid -import json -from datetime import datetime -from aiohttp import ClientSession - -from ...typing import SHA256, AsyncResult, Messages -from ..base_provider import AsyncGeneratorProvider - - -class Ails(AsyncGeneratorProvider): - url = "https://ai.ls" - working = False - supports_message_history = True - supports_gpt_35_turbo = True - - @staticmethod - async def create_async_generator( - model: str, - messages: Messages, - stream: bool, - proxy: str = None, - **kwargs - ) -> AsyncResult: - headers = { - "authority": "api.caipacity.com", - "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", - "authorization": "Bearer free", - "client-id": str(uuid.uuid4()), - "client-v": "0.1.278", - "content-type": "application/json", - "origin": "https://ai.ls", - "referer": "https://ai.ls/", - "sec-ch-ua": '"Not.A/Brand";v="8", "Chromium";v="114", "Google Chrome";v="114"', - "sec-ch-ua-mobile": "?0", - "sec-ch-ua-platform": '"Windows"', - "sec-fetch-dest": "empty", - "sec-fetch-mode": "cors", - "sec-fetch-site": "cross-site", - "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36", - "from-url": "https://ai.ls/?chat=1" - } - async with ClientSession( - headers=headers - ) as session: - timestamp = _format_timestamp(int(time.time() * 1000)) - json_data = { - "model": "gpt-3.5-turbo", - "temperature": kwargs.get("temperature", 0.6), - "stream": True, - "messages": messages, - "d": datetime.now().strftime("%Y-%m-%d"), - "t": timestamp, - "s": _hash({"t": timestamp, "m": messages[-1]["content"]}), - } - async with session.post( - "https://api.caipacity.com/v1/chat/completions", - proxy=proxy, - json=json_data - ) as response: - response.raise_for_status() - start = "data: " - async for line in response.content: - line = line.decode('utf-8') - if line.startswith(start) and line != "data: [DONE]": - line = line[len(start):-1] - line = json.loads(line) - token = line["choices"][0]["delta"].get("content") - - if token: - if "ai.ls" in token or "ai.ci" in token: - raise Exception(f"Response Error: {token}") - yield token - - -def _hash(json_data: dict[str, str]) -> SHA256: - base_string: str = f'{json_data["t"]}:{json_data["m"]}:WI,2rU#_r:r~aF4aJ36[.Z(/8Rv93Rf:{len(json_data["m"])}' - - return SHA256(hashlib.sha256(base_string.encode()).hexdigest()) - - -def _format_timestamp(timestamp: int) -> str: - e = timestamp - n = e % 10 - r = n + 1 if n % 2 == 0 else n - return str(e - n + r) \ No newline at end of file diff --git a/g4f/Provider/deprecated/Aivvm.py b/g4f/Provider/deprecated/Aivvm.py deleted file mode 100644 index c973adf8..00000000 --- a/g4f/Provider/deprecated/Aivvm.py +++ /dev/null @@ -1,73 +0,0 @@ -from __future__ import annotations - -import requests -import json - -from ..base_provider import AbstractProvider -from ...typing import CreateResult, Messages - -# to recreate this easily, send a post request to https://chat.aivvm.com/api/models -models = { - 'gpt-3.5-turbo': {'id': 'gpt-3.5-turbo', 'name': 'GPT-3.5'}, - 'gpt-3.5-turbo-0613': {'id': 'gpt-3.5-turbo-0613', 'name': 'GPT-3.5-0613'}, - 'gpt-3.5-turbo-16k': {'id': 'gpt-3.5-turbo-16k', 'name': 'GPT-3.5-16K'}, - 'gpt-3.5-turbo-16k-0613': {'id': 'gpt-3.5-turbo-16k-0613', 'name': 'GPT-3.5-16K-0613'}, - 'gpt-4': {'id': 'gpt-4', 'name': 'GPT-4'}, - 'gpt-4-0613': {'id': 'gpt-4-0613', 'name': 'GPT-4-0613'}, - 'gpt-4-32k': {'id': 'gpt-4-32k', 'name': 'GPT-4-32K'}, - 'gpt-4-32k-0613': {'id': 'gpt-4-32k-0613', 'name': 'GPT-4-32K-0613'}, -} - -class Aivvm(AbstractProvider): - url = 'https://chat.aivvm.com' - supports_stream = True - working = False - supports_gpt_35_turbo = True - supports_gpt_4 = True - - @classmethod - def create_completion(cls, - model: str, - messages: Messages, - stream: bool, - **kwargs - ) -> CreateResult: - if not model: - model = "gpt-3.5-turbo" - elif model not in models: - raise ValueError(f"Model is not supported: {model}") - - json_data = { - "model" : models[model], - "messages" : messages, - "key" : "", - "prompt" : kwargs.get("system_message", "You are ChatGPT, a large language model trained by OpenAI. Follow the user's instructions carefully. Respond using markdown."), - "temperature" : kwargs.get("temperature", 0.7) - } - - data = json.dumps(json_data) - - headers = { - "accept" : "text/event-stream", - "accept-language" : "en-US,en;q=0.9", - "content-type" : "application/json", - "content-length" : str(len(data)), - "sec-ch-ua" : "\"Chrome\";v=\"117\", \"Not;A=Brand\";v=\"8\", \"Chromium\";v=\"117\"", - "sec-ch-ua-mobile" : "?0", - "sec-ch-ua-platform": "\"Windows\"", - "sec-fetch-dest" : "empty", - "sec-fetch-mode" : "cors", - "sec-fetch-site" : "same-origin", - "sec-gpc" : "1", - "referrer" : "https://chat.aivvm.com/", - "user-agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36" - } - - response = requests.post("https://chat.aivvm.com/api/chat", headers=headers, data=data, stream=True) - response.raise_for_status() - - for chunk in response.iter_content(chunk_size=4096): - try: - yield chunk.decode("utf-8") - except UnicodeDecodeError: - yield chunk.decode("unicode-escape") \ No newline at end of file diff --git a/g4f/Provider/deprecated/Berlin.py b/g4f/Provider/deprecated/Berlin.py deleted file mode 100644 index 5e81705a..00000000 --- a/g4f/Provider/deprecated/Berlin.py +++ /dev/null @@ -1,78 +0,0 @@ -from __future__ import annotations - -import secrets -import uuid -import json -from aiohttp import ClientSession - -from ...typing import AsyncResult, Messages -from ..base_provider import AsyncGeneratorProvider -from ..helper import format_prompt - - -class Berlin(AsyncGeneratorProvider): - url = "https://ai.berlin4h.top" - working = False - supports_gpt_35_turbo = True - _token = None - - @classmethod - async def create_async_generator( - cls, - model: str, - messages: Messages, - proxy: str = None, - **kwargs - ) -> AsyncResult: - if not model: - model = "gpt-3.5-turbo" - headers = { - "User-Agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/119.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": "application/json", - "Origin": cls.url, - "Alt-Used": "ai.berlin4h.top", - "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: - if not cls._token: - data = { - "account": '免费使用GPT3.5模型@163.com', - "password": '659e945c2d004686bad1a75b708c962f' - } - async with session.post(f"{cls.url}/api/login", json=data, proxy=proxy) as response: - response.raise_for_status() - cls._token = (await response.json())["data"]["token"] - headers = { - "token": cls._token - } - prompt = format_prompt(messages) - data = { - "prompt": prompt, - "parentMessageId": str(uuid.uuid4()), - "options": { - "model": model, - "temperature": 0, - "presence_penalty": 0, - "frequency_penalty": 0, - "max_tokens": 1888, - **kwargs - }, - } - async with session.post(f"{cls.url}/api/chat/completions", json=data, proxy=proxy, headers=headers) as response: - response.raise_for_status() - async for chunk in response.content: - if chunk.strip(): - try: - yield json.loads(chunk)["content"] - except: - raise RuntimeError(f"Response: {chunk.decode()}") diff --git a/g4f/Provider/deprecated/ChatAnywhere.py b/g4f/Provider/deprecated/ChatAnywhere.py deleted file mode 100644 index d035eaf0..00000000 --- a/g4f/Provider/deprecated/ChatAnywhere.py +++ /dev/null @@ -1,54 +0,0 @@ -from __future__ import annotations - -from aiohttp import ClientSession, ClientTimeout - -from ...typing import AsyncResult, Messages -from ..base_provider import AsyncGeneratorProvider - - -class ChatAnywhere(AsyncGeneratorProvider): - url = "https://chatanywhere.cn" - supports_gpt_35_turbo = True - supports_message_history = True - working = False - - @classmethod - async def create_async_generator( - cls, - model: str, - messages: Messages, - proxy: str = None, - timeout: int = 120, - temperature: float = 0.5, - **kwargs - ) -> AsyncResult: - headers = { - "User-Agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/119.0", - "Accept": "application/json, text/plain, */*", - "Accept-Language": "de,en-US;q=0.7,en;q=0.3", - "Accept-Encoding": "gzip, deflate, br", - "Content-Type": "application/json", - "Referer": f"{cls.url}/", - "Origin": cls.url, - "Sec-Fetch-Dest": "empty", - "Sec-Fetch-Mode": "cors", - "Sec-Fetch-Site": "same-origin", - "Authorization": "", - "Connection": "keep-alive", - "TE": "trailers" - } - async with ClientSession(headers=headers, timeout=ClientTimeout(timeout)) as session: - data = { - "list": messages, - "id": "s1_qYuOLXjI3rEpc7WHfQ", - "title": messages[-1]["content"], - "prompt": "", - "temperature": temperature, - "models": "61490748", - "continuous": True - } - async with session.post(f"{cls.url}/v1/chat/gpt/", json=data, proxy=proxy) as response: - response.raise_for_status() - async for chunk in response.content.iter_any(): - if chunk: - yield chunk.decode() \ No newline at end of file diff --git a/g4f/Provider/deprecated/ChatgptDuo.py b/g4f/Provider/deprecated/ChatgptDuo.py deleted file mode 100644 index bd9e195d..00000000 --- a/g4f/Provider/deprecated/ChatgptDuo.py +++ /dev/null @@ -1,47 +0,0 @@ -from __future__ import annotations - -from ...typing import Messages -from ...requests import StreamSession -from ..base_provider import AsyncProvider, format_prompt - - -class ChatgptDuo(AsyncProvider): - url = "https://chatgptduo.com" - supports_gpt_35_turbo = True - working = False - - @classmethod - async def create_async( - cls, - model: str, - messages: Messages, - proxy: str = None, - timeout: int = 120, - **kwargs - ) -> str: - async with StreamSession( - impersonate="chrome107", - proxies={"https": proxy}, - timeout=timeout - ) as session: - prompt = format_prompt(messages), - data = { - "prompt": prompt, - "search": prompt, - "purpose": "ask", - } - response = await session.post(f"{cls.url}/", data=data) - response.raise_for_status() - data = response.json() - - cls._sources = [{ - "title": source["title"], - "url": source["link"], - "snippet": source["snippet"] - } for source in data["results"]] - - return data["answer"] - - @classmethod - def get_sources(cls): - return cls._sources \ No newline at end of file diff --git a/g4f/Provider/deprecated/CodeLinkAva.py b/g4f/Provider/deprecated/CodeLinkAva.py deleted file mode 100644 index 22f4468a..00000000 --- a/g4f/Provider/deprecated/CodeLinkAva.py +++ /dev/null @@ -1,52 +0,0 @@ -from __future__ import annotations - -from aiohttp import ClientSession -import json - -from ...typing import AsyncGenerator -from ..base_provider import AsyncGeneratorProvider - - -class CodeLinkAva(AsyncGeneratorProvider): - url = "https://ava-ai-ef611.web.app" - supports_gpt_35_turbo = True - working = False - - @classmethod - async def create_async_generator( - cls, - model: str, - messages: list[dict[str, str]], - **kwargs - ) -> AsyncGenerator: - headers = { - "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36", - "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", - "Origin": cls.url, - "Referer": f"{cls.url}/", - "Sec-Fetch-Dest": "empty", - "Sec-Fetch-Mode": "cors", - "Sec-Fetch-Site": "same-origin", - } - async with ClientSession( - headers=headers - ) as session: - data = { - "messages": messages, - "temperature": 0.6, - "stream": True, - **kwargs - } - async with session.post("https://ava-alpha-api.codelink.io/api/chat", json=data) as response: - response.raise_for_status() - async for line in response.content: - line = line.decode() - if line.startswith("data: "): - if line.startswith("data: [DONE]"): - break - line = json.loads(line[6:-1]) - - content = line["choices"][0]["delta"].get("content") - if content: - yield content \ No newline at end of file diff --git a/g4f/Provider/deprecated/Cromicle.py b/g4f/Provider/deprecated/Cromicle.py deleted file mode 100644 index 9f986cb5..00000000 --- a/g4f/Provider/deprecated/Cromicle.py +++ /dev/null @@ -1,50 +0,0 @@ -from __future__ import annotations - -from aiohttp import ClientSession -from hashlib import sha256 -from ...typing import AsyncResult, Messages, Dict - -from ..base_provider import AsyncGeneratorProvider -from ..helper import format_prompt - - -class Cromicle(AsyncGeneratorProvider): - url: str = 'https://cromicle.top' - working: bool = False - supports_gpt_35_turbo: bool = True - - @classmethod - async def create_async_generator( - cls, - model: str, - messages: Messages, - proxy: str = None, - **kwargs - ) -> AsyncResult: - async with ClientSession( - headers=_create_header() - ) as session: - async with session.post( - f'{cls.url}/chat', - proxy=proxy, - json=_create_payload(format_prompt(messages)) - ) as response: - response.raise_for_status() - async for stream in response.content.iter_any(): - if stream: - yield stream.decode() - - -def _create_header() -> Dict[str, str]: - return { - 'accept': '*/*', - 'content-type': 'application/json', - } - - -def _create_payload(message: str) -> Dict[str, str]: - return { - 'message': message, - 'token': 'abc', - 'hash': sha256('abc'.encode() + message.encode()).hexdigest() - } \ No newline at end of file diff --git a/g4f/Provider/deprecated/DfeHub.py b/g4f/Provider/deprecated/DfeHub.py deleted file mode 100644 index e6d13444..00000000 --- a/g4f/Provider/deprecated/DfeHub.py +++ /dev/null @@ -1,62 +0,0 @@ -from __future__ import annotations - -import json -import re -import time - -import requests - -from ...typing import Any, CreateResult -from ..base_provider import AbstractProvider - - -class DfeHub(AbstractProvider): - url = "https://chat.dfehub.com/" - supports_stream = True - supports_gpt_35_turbo = True - - @staticmethod - def create_completion( - model: str, - messages: list[dict[str, str]], - stream: bool, **kwargs: Any) -> CreateResult: - - headers = { - "authority" : "chat.dfehub.com", - "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", - "content-type" : "application/json", - "origin" : "https://chat.dfehub.com", - "referer" : "https://chat.dfehub.com/", - "sec-ch-ua" : '"Not.A/Brand";v="8", "Chromium";v="114", "Google Chrome";v="114"', - "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/114.0.0.0 Safari/537.36", - "x-requested-with" : "XMLHttpRequest", - } - - json_data = { - "messages" : messages, - "model" : "gpt-3.5-turbo", - "temperature" : kwargs.get("temperature", 0.5), - "presence_penalty" : kwargs.get("presence_penalty", 0), - "frequency_penalty" : kwargs.get("frequency_penalty", 0), - "top_p" : kwargs.get("top_p", 1), - "stream" : True - } - - response = requests.post("https://chat.dfehub.com/api/openai/v1/chat/completions", - headers=headers, json=json_data, timeout=3) - - for chunk in response.iter_lines(): - if b"detail" in chunk: - delay = re.findall(r"\d+\.\d+", chunk.decode()) - delay = float(delay[-1]) - time.sleep(delay) - yield from DfeHub.create_completion(model, messages, stream, **kwargs) - if b"content" in chunk: - data = json.loads(chunk.decode().split("data: ")[1]) - yield (data["choices"][0]["delta"]["content"]) diff --git a/g4f/Provider/deprecated/EasyChat.py b/g4f/Provider/deprecated/EasyChat.py deleted file mode 100644 index 7a00f523..00000000 --- a/g4f/Provider/deprecated/EasyChat.py +++ /dev/null @@ -1,89 +0,0 @@ -from __future__ import annotations - -import json -import random -import requests - -from ...typing import Any, CreateResult -from ..base_provider import AbstractProvider - - -class EasyChat(AbstractProvider): - url: str = "https://free.easychat.work" - supports_stream = True - supports_gpt_35_turbo = True - working = False - - @staticmethod - def create_completion( - model: str, - messages: list[dict[str, str]], - stream: bool, **kwargs: Any) -> CreateResult: - - active_servers = [ - "https://chat10.fastgpt.me", - "https://chat9.fastgpt.me", - "https://chat1.fastgpt.me", - "https://chat2.fastgpt.me", - "https://chat3.fastgpt.me", - "https://chat4.fastgpt.me", - "https://gxos1h1ddt.fastgpt.me" - ] - - server = active_servers[kwargs.get("active_server", random.randint(0, 5))] - headers = { - "authority" : f"{server}".replace("https://", ""), - "accept" : "text/event-stream", - "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,fa=0.2", - "content-type" : "application/json", - "origin" : f"{server}", - "referer" : f"{server}/", - "x-requested-with" : "XMLHttpRequest", - 'plugins' : '0', - 'sec-ch-ua' : '"Chromium";v="116", "Not)A;Brand";v="24", "Google Chrome";v="116"', - 'sec-ch-ua-mobile' : '?0', - 'sec-ch-ua-platform': '"Windows"', - 'sec-fetch-dest' : 'empty', - 'sec-fetch-mode' : 'cors', - 'sec-fetch-site' : 'same-origin', - 'user-agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36', - 'usesearch' : 'false', - 'x-requested-with' : 'XMLHttpRequest' - } - - json_data = { - "messages" : messages, - "stream" : stream, - "model" : model, - "temperature" : kwargs.get("temperature", 0.5), - "presence_penalty" : kwargs.get("presence_penalty", 0), - "frequency_penalty" : kwargs.get("frequency_penalty", 0), - "top_p" : kwargs.get("top_p", 1) - } - - session = requests.Session() - # init cookies from server - session.get(f"{server}/") - - response = session.post(f"{server}/api/openai/v1/chat/completions", - headers=headers, json=json_data, stream=stream) - - if response.status_code != 200: - raise Exception(f"Error {response.status_code} from server : {response.reason}") - if not stream: - json_data = response.json() - - if "choices" in json_data: - yield json_data["choices"][0]["message"]["content"] - else: - raise Exception("No response from server") - - else: - - for chunk in response.iter_lines(): - - if b"content" in chunk: - splitData = chunk.decode().split("data:") - - if len(splitData) > 1: - yield json.loads(splitData[1])["choices"][0]["delta"]["content"] \ No newline at end of file diff --git a/g4f/Provider/deprecated/Equing.py b/g4f/Provider/deprecated/Equing.py deleted file mode 100644 index 5fd9797b..00000000 --- a/g4f/Provider/deprecated/Equing.py +++ /dev/null @@ -1,71 +0,0 @@ -from __future__ import annotations - -import json -from abc import ABC, abstractmethod - -import requests - -from ...typing import Any, CreateResult -from ..base_provider import AbstractProvider - - -class Equing(AbstractProvider): - url: str = 'https://next.eqing.tech/' - working = False - supports_stream = True - supports_gpt_35_turbo = True - supports_gpt_4 = False - - @staticmethod - @abstractmethod - def create_completion( - model: str, - messages: list[dict[str, str]], - stream: bool, **kwargs: Any) -> CreateResult: - - headers = { - 'authority' : 'next.eqing.tech', - 'accept' : 'text/event-stream', - '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', - 'origin' : 'https://next.eqing.tech', - 'plugins' : '0', - 'pragma' : 'no-cache', - 'referer' : 'https://next.eqing.tech/', - 'sec-ch-ua' : '"Not/A)Brand";v="99", "Google Chrome";v="115", "Chromium";v="115"', - '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/115.0.0.0 Safari/537.36', - 'usesearch' : 'false', - 'x-requested-with' : 'XMLHttpRequest' - } - - json_data = { - 'messages' : messages, - 'stream' : stream, - 'model' : model, - 'temperature' : kwargs.get('temperature', 0.5), - 'presence_penalty' : kwargs.get('presence_penalty', 0), - 'frequency_penalty' : kwargs.get('frequency_penalty', 0), - 'top_p' : kwargs.get('top_p', 1), - } - - response = requests.post('https://next.eqing.tech/api/openai/v1/chat/completions', - headers=headers, json=json_data, stream=stream) - - if not stream: - yield response.json()["choices"][0]["message"]["content"] - return - - for line in response.iter_content(chunk_size=1024): - if line: - if b'content' in line: - line_json = json.loads(line.decode('utf-8').split('data: ')[1]) - - token = line_json['choices'][0]['delta'].get('content') - if token: - yield token \ No newline at end of file diff --git a/g4f/Provider/deprecated/FakeGpt.py b/g4f/Provider/deprecated/FakeGpt.py deleted file mode 100644 index 99b6bb1a..00000000 --- a/g4f/Provider/deprecated/FakeGpt.py +++ /dev/null @@ -1,91 +0,0 @@ -from __future__ import annotations - -import uuid, time, random, json -from aiohttp import ClientSession - -from ...typing import AsyncResult, Messages -from ..base_provider import AsyncGeneratorProvider -from ..helper import format_prompt, get_random_string - - -class FakeGpt(AsyncGeneratorProvider): - url = "https://chat-shared2.zhile.io" - supports_gpt_35_turbo = True - working = False - _access_token = None - _cookie_jar = None - - @classmethod - async def create_async_generator( - cls, - model: str, - messages: Messages, - proxy: str = None, - **kwargs - ) -> AsyncResult: - headers = { - "Accept-Language": "en-US", - "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36", - "Referer": "https://chat-shared2.zhile.io/?v=2", - "sec-ch-ua": '"Google Chrome";v="117", "Not;A=Brand";v="8", "Chromium";v="117"', - "sec-ch-ua-platform": '"Linux"', - "sec-ch-ua-mobile": "?0", - } - async with ClientSession(headers=headers, cookie_jar=cls._cookie_jar) as session: - if not cls._access_token: - async with session.get(f"{cls.url}/api/loads", params={"t": int(time.time())}, proxy=proxy) as response: - response.raise_for_status() - list = (await response.json())["loads"] - token_ids = [t["token_id"] for t in list] - data = { - "token_key": random.choice(token_ids), - "session_password": get_random_string() - } - async with session.post(f"{cls.url}/auth/login", data=data, proxy=proxy) as response: - response.raise_for_status() - async with session.get(f"{cls.url}/api/auth/session", proxy=proxy) as response: - response.raise_for_status() - cls._access_token = (await response.json())["accessToken"] - cls._cookie_jar = session.cookie_jar - headers = { - "Content-Type": "application/json", - "Accept": "text/event-stream", - "X-Authorization": f"Bearer {cls._access_token}", - } - prompt = format_prompt(messages) - data = { - "action": "next", - "messages": [ - { - "id": str(uuid.uuid4()), - "author": {"role": "user"}, - "content": {"content_type": "text", "parts": [prompt]}, - "metadata": {}, - } - ], - "parent_message_id": str(uuid.uuid4()), - "model": "text-davinci-002-render-sha", - "plugin_ids": [], - "timezone_offset_min": -120, - "suggestions": [], - "history_and_training_disabled": True, - "arkose_token": "", - "force_paragen": False, - } - last_message = "" - async with session.post(f"{cls.url}/api/conversation", json=data, headers=headers, proxy=proxy) as response: - async for line in response.content: - if line.startswith(b"data: "): - line = line[6:] - if line == b"[DONE]": - break - try: - line = json.loads(line) - if line["message"]["metadata"]["message_type"] == "next": - new_message = line["message"]["content"]["parts"][0] - yield new_message[len(last_message):] - last_message = new_message - except: - continue - if not last_message: - raise RuntimeError("No valid response") \ No newline at end of file diff --git a/g4f/Provider/deprecated/FastGpt.py b/g4f/Provider/deprecated/FastGpt.py deleted file mode 100644 index 6a79d9aa..00000000 --- a/g4f/Provider/deprecated/FastGpt.py +++ /dev/null @@ -1,76 +0,0 @@ -from __future__ import annotations - -import json -import random -import requests - -from ...typing import Any, CreateResult -from ..base_provider import AbstractProvider - - -class FastGpt(AbstractProvider): - url: str = 'https://chat9.fastgpt.me/' - working = False - needs_auth = False - supports_stream = True - supports_gpt_35_turbo = True - supports_gpt_4 = False - - @staticmethod - def create_completion( - model: str, - messages: list[dict[str, str]], - stream: bool, **kwargs: Any) -> CreateResult: - - headers = { - 'authority' : 'chat9.fastgpt.me', - 'accept' : 'text/event-stream', - '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', - 'origin' : 'https://chat9.fastgpt.me', - 'plugins' : '0', - 'pragma' : 'no-cache', - 'referer' : 'https://chat9.fastgpt.me/', - 'sec-ch-ua' : '"Not/A)Brand";v="99", "Google Chrome";v="115", "Chromium";v="115"', - '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/115.0.0.0 Safari/537.36', - 'usesearch' : 'false', - 'x-requested-with' : 'XMLHttpRequest', - } - - json_data = { - 'messages' : messages, - 'stream' : stream, - 'model' : model, - 'temperature' : kwargs.get('temperature', 0.5), - 'presence_penalty' : kwargs.get('presence_penalty', 0), - 'frequency_penalty' : kwargs.get('frequency_penalty', 0), - 'top_p' : kwargs.get('top_p', 1), - } - - subdomain = random.choice([ - 'jdaen979ew', - 'chat9' - ]) - - response = requests.post(f'https://{subdomain}.fastgpt.me/api/openai/v1/chat/completions', - headers=headers, json=json_data, stream=stream) - - for line in response.iter_lines(): - if line: - try: - if b'content' in line: - line_json = json.loads(line.decode('utf-8').split('data: ')[1]) - token = line_json['choices'][0]['delta'].get( - 'content' - ) - - if token: - yield token - except: - continue \ No newline at end of file diff --git a/g4f/Provider/deprecated/Forefront.py b/g4f/Provider/deprecated/Forefront.py deleted file mode 100644 index 39654b2c..00000000 --- a/g4f/Provider/deprecated/Forefront.py +++ /dev/null @@ -1,40 +0,0 @@ -from __future__ import annotations - -import json - -import requests - -from ...typing import Any, CreateResult -from ..base_provider import AbstractProvider - - -class Forefront(AbstractProvider): - url = "https://forefront.com" - supports_stream = True - supports_gpt_35_turbo = True - - @staticmethod - def create_completion( - model: str, - messages: list[dict[str, str]], - stream: bool, **kwargs: Any) -> CreateResult: - - json_data = { - "text" : messages[-1]["content"], - "action" : "noauth", - "id" : "", - "parentId" : "", - "workspaceId" : "", - "messagePersona": "607e41fe-95be-497e-8e97-010a59b2e2c0", - "model" : "gpt-4", - "messages" : messages[:-1] if len(messages) > 1 else [], - "internetMode" : "auto", - } - - response = requests.post("https://streaming.tenant-forefront-default.knative.chi.coreweave.com/free-chat", - json=json_data, stream=True) - - response.raise_for_status() - for token in response.iter_lines(): - if b"delta" in token: - yield json.loads(token.decode().split("data: ")[1])["delta"] diff --git a/g4f/Provider/deprecated/GPTalk.py b/g4f/Provider/deprecated/GPTalk.py deleted file mode 100644 index 5b36d37b..00000000 --- a/g4f/Provider/deprecated/GPTalk.py +++ /dev/null @@ -1,87 +0,0 @@ -from __future__ import annotations - -import secrets, time, json -from aiohttp import ClientSession - -from ...typing import AsyncResult, Messages -from ..base_provider import AsyncGeneratorProvider -from ..helper import format_prompt - - -class GPTalk(AsyncGeneratorProvider): - url = "https://gptalk.net" - working = False - supports_gpt_35_turbo = True - _auth = None - used_times = 0 - - @classmethod - async def create_async_generator( - cls, - model: str, - messages: Messages, - proxy: str = None, - **kwargs - ) -> AsyncResult: - if not model: - model = "gpt-3.5-turbo" - timestamp = int(time.time()) - headers = { - 'authority': 'gptalk.net', - 'accept': '*/*', - 'accept-language': 'de-DE,de;q=0.9,en-DE;q=0.8,en;q=0.7,en-US;q=0.6,nl;q=0.5,zh-CN;q=0.4,zh-TW;q=0.3,zh;q=0.2', - 'content-type': 'application/json', - 'origin': 'https://gptalk.net', - 'sec-ch-ua': '"Google Chrome";v="117", "Not;A=Brand";v="8", "Chromium";v="117"', - '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/117.0.0.0 Safari/537.36', - 'x-auth-appid': '2229', - 'x-auth-openid': '', - 'x-auth-platform': '', - 'x-auth-timestamp': f"{timestamp}", - } - async with ClientSession(headers=headers) as session: - if not cls._auth or cls._auth["expires_at"] < timestamp or cls.used_times == 5: - data = { - "fingerprint": secrets.token_hex(16).zfill(32), - "platform": "fingerprint" - } - async with session.post(f"{cls.url}/api/chatgpt/user/login", json=data, proxy=proxy) as response: - response.raise_for_status() - cls._auth = (await response.json())["data"] - cls.used_times = 0 - data = { - "content": format_prompt(messages), - "accept": "stream", - "from": 1, - "model": model, - "is_mobile": 0, - "user_agent": headers["user-agent"], - "is_open_ctx": 0, - "prompt": "", - "roid": 111, - "temperature": 0, - "ctx_msg_count": 3, - "created_at": timestamp - } - headers = { - 'authorization': f'Bearer {cls._auth["token"]}', - } - async with session.post(f"{cls.url}/api/chatgpt/chatapi/text", json=data, headers=headers, proxy=proxy) as response: - response.raise_for_status() - token = (await response.json())["data"]["token"] - cls.used_times += 1 - last_message = "" - async with session.get(f"{cls.url}/api/chatgpt/chatapi/stream", params={"token": token}, proxy=proxy) as response: - response.raise_for_status() - async for line in response.content: - if line.startswith(b"data: "): - if line.startswith(b"data: [DONE]"): - break - message = json.loads(line[6:-1])["content"] - yield message[len(last_message):] - last_message = message diff --git a/g4f/Provider/deprecated/GeekGpt.py b/g4f/Provider/deprecated/GeekGpt.py deleted file mode 100644 index 7a460083..00000000 --- a/g4f/Provider/deprecated/GeekGpt.py +++ /dev/null @@ -1,73 +0,0 @@ -from __future__ import annotations -import requests, json - -from ..base_provider import AbstractProvider -from ...typing import CreateResult, Messages -from json import dumps - - -class GeekGpt(AbstractProvider): - url = 'https://chat.geekgpt.org' - working = False - supports_message_history = True - supports_stream = True - supports_gpt_35_turbo = True - supports_gpt_4 = True - - @classmethod - def create_completion( - cls, - model: str, - messages: Messages, - stream: bool, - **kwargs - ) -> CreateResult: - if not model: - model = "gpt-3.5-turbo" - json_data = { - 'messages': messages, - 'model': model, - 'temperature': kwargs.get('temperature', 0.9), - 'presence_penalty': kwargs.get('presence_penalty', 0), - 'top_p': kwargs.get('top_p', 1), - 'frequency_penalty': kwargs.get('frequency_penalty', 0), - 'stream': True - } - - data = dumps(json_data, separators=(',', ':')) - - headers = { - 'authority': 'ai.fakeopen.com', - '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', - 'authorization': 'Bearer pk-this-is-a-real-free-pool-token-for-everyone', - 'content-type': 'application/json', - 'origin': 'https://chat.geekgpt.org', - 'referer': 'https://chat.geekgpt.org/', - 'sec-ch-ua': '"Chromium";v="118", "Google Chrome";v="118", "Not=A?Brand";v="99"', - 'sec-ch-ua-mobile': '?0', - 'sec-ch-ua-platform': '"macOS"', - 'sec-fetch-dest': 'empty', - 'sec-fetch-mode': 'cors', - 'sec-fetch-site': 'cross-site', - 'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36', - } - - response = requests.post("https://ai.fakeopen.com/v1/chat/completions", - headers=headers, data=data, stream=True) - response.raise_for_status() - - for chunk in response.iter_lines(): - if b'content' in chunk: - json_data = chunk.decode().replace("data: ", "") - - if json_data == "[DONE]": - break - - try: - content = json.loads(json_data)["choices"][0]["delta"].get("content") - except Exception as e: - raise RuntimeError(f'error | {e} :', json_data) - - if content: - yield content \ No newline at end of file diff --git a/g4f/Provider/deprecated/GetGpt.py b/g4f/Provider/deprecated/GetGpt.py deleted file mode 100644 index dd586569..00000000 --- a/g4f/Provider/deprecated/GetGpt.py +++ /dev/null @@ -1,77 +0,0 @@ -from __future__ import annotations - -import json -import os -import uuid - -import requests -# try: -# from Crypto.Cipher import AES -# except ImportError: -# from Cryptodome.Cipher import AES - -from ...typing import Any, CreateResult -from ..base_provider import AbstractProvider - - -class GetGpt(AbstractProvider): - url = 'https://chat.getgpt.world/' - supports_stream = True - working = False - supports_gpt_35_turbo = True - - @staticmethod - def create_completion( - model: str, - messages: list[dict[str, str]], - stream: bool, **kwargs: Any) -> CreateResult: - - headers = { - 'Content-Type' : 'application/json', - 'Referer' : 'https://chat.getgpt.world/', - 'user-agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36', - } - - data = json.dumps( - { - 'messages' : messages, - 'frequency_penalty' : kwargs.get('frequency_penalty', 0), - 'max_tokens' : kwargs.get('max_tokens', 4000), - 'model' : 'gpt-3.5-turbo', - 'presence_penalty' : kwargs.get('presence_penalty', 0), - 'temperature' : kwargs.get('temperature', 1), - 'top_p' : kwargs.get('top_p', 1), - 'stream' : True, - 'uuid' : str(uuid.uuid4()) - } - ) - - res = requests.post('https://chat.getgpt.world/api/chat/stream', - headers=headers, json={'signature': _encrypt(data)}, stream=True) - - res.raise_for_status() - for line in res.iter_lines(): - if b'content' in line: - line_json = json.loads(line.decode('utf-8').split('data: ')[1]) - yield (line_json['choices'][0]['delta']['content']) - - -def _encrypt(e: str): - # t = os.urandom(8).hex().encode('utf-8') - # n = os.urandom(8).hex().encode('utf-8') - # r = e.encode('utf-8') - - # cipher = AES.new(t, AES.MODE_CBC, n) - # ciphertext = cipher.encrypt(_pad_data(r)) - - # return ciphertext.hex() + t.decode('utf-8') + n.decode('utf-8') - return - - -def _pad_data(data: bytes) -> bytes: - # block_size = AES.block_size - # padding_size = block_size - len(data) % block_size - # padding = bytes([padding_size] * padding_size) - - # return data + padding - return \ No newline at end of file diff --git a/g4f/Provider/deprecated/H2o.py b/g4f/Provider/deprecated/H2o.py deleted file mode 100644 index ba4ca507..00000000 --- a/g4f/Provider/deprecated/H2o.py +++ /dev/null @@ -1,89 +0,0 @@ -from __future__ import annotations - -import json -import uuid - -from aiohttp import ClientSession - -from ...typing import AsyncResult, Messages -from ..base_provider import AsyncGeneratorProvider, format_prompt - - -class H2o(AsyncGeneratorProvider): - url = "https://gpt-gm.h2o.ai" - model = "h2oai/h2ogpt-gm-oasst1-en-2048-falcon-40b-v1" - - @classmethod - async def create_async_generator( - cls, - model: str, - messages: Messages, - proxy: str = None, - **kwargs - ) -> AsyncResult: - model = model if model else cls.model - headers = {"Referer": f"{cls.url}/"} - - async with ClientSession( - headers=headers - ) as session: - data = { - "ethicsModalAccepted": "true", - "shareConversationsWithModelAuthors": "true", - "ethicsModalAcceptedAt": "", - "activeModel": model, - "searchEnabled": "true", - } - async with session.post( - f"{cls.url}/settings", - proxy=proxy, - data=data - ) as response: - response.raise_for_status() - - async with session.post( - f"{cls.url}/conversation", - proxy=proxy, - json={"model": model}, - ) as response: - response.raise_for_status() - conversationId = (await response.json())["conversationId"] - - data = { - "inputs": format_prompt(messages), - "parameters": { - "temperature": 0.4, - "truncate": 2048, - "max_new_tokens": 1024, - "do_sample": True, - "repetition_penalty": 1.2, - "return_full_text": False, - **kwargs - }, - "stream": True, - "options": { - "id": str(uuid.uuid4()), - "response_id": str(uuid.uuid4()), - "is_retry": False, - "use_cache": False, - "web_search_id": "", - }, - } - async with session.post( - f"{cls.url}/conversation/{conversationId}", - proxy=proxy, - json=data - ) as response: - start = "data:" - async for line in response.content: - line = line.decode("utf-8") - if line and line.startswith(start): - line = json.loads(line[len(start):-1]) - if not line["token"]["special"]: - yield line["token"]["text"] - - async with session.delete( - f"{cls.url}/conversation/{conversationId}", - proxy=proxy, - ) as response: - response.raise_for_status() \ No newline at end of file diff --git a/g4f/Provider/deprecated/Hashnode.py b/g4f/Provider/deprecated/Hashnode.py deleted file mode 100644 index c2c0ffb7..00000000 --- a/g4f/Provider/deprecated/Hashnode.py +++ /dev/null @@ -1,80 +0,0 @@ -from __future__ import annotations - -from aiohttp import ClientSession - -from ...typing import AsyncResult, Messages -from ..base_provider import AsyncGeneratorProvider -from ..helper import get_random_hex - -class SearchTypes(): - quick = "quick" - code = "code" - websearch = "websearch" - -class Hashnode(AsyncGeneratorProvider): - url = "https://hashnode.com" - working = False - supports_message_history = True - supports_gpt_35_turbo = True - _sources = [] - - @classmethod - async def create_async_generator( - cls, - model: str, - messages: Messages, - search_type: str = SearchTypes.websearch, - 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", - "Referer": f"{cls.url}/rix", - "Content-Type": "application/json", - "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: - prompt = messages[-1]["content"] - cls._sources = [] - if search_type == "websearch": - async with session.post( - f"{cls.url}/api/ai/rix/search", - json={"prompt": prompt}, - proxy=proxy, - ) as response: - response.raise_for_status() - cls._sources = (await response.json())["result"] - data = { - "chatId": get_random_hex(), - "history": messages, - "prompt": prompt, - "searchType": search_type, - "urlToScan": None, - "searchResults": cls._sources, - } - async with session.post( - f"{cls.url}/api/ai/rix/completion", - json=data, - proxy=proxy, - ) as response: - response.raise_for_status() - async for chunk in response.content.iter_any(): - if chunk: - yield chunk.decode() - - @classmethod - def get_sources(cls) -> list: - return [{ - "title": source["name"], - "url": source["url"] - } for source in cls._sources] \ No newline at end of file diff --git a/g4f/Provider/deprecated/Lockchat.py b/g4f/Provider/deprecated/Lockchat.py deleted file mode 100644 index edab0bd4..00000000 --- a/g4f/Provider/deprecated/Lockchat.py +++ /dev/null @@ -1,54 +0,0 @@ -from __future__ import annotations - -import json - -import requests - -from ...typing import Any, CreateResult -from ..base_provider import AbstractProvider - - -class Lockchat(AbstractProvider): - url: str = "http://supertest.lockchat.app" - supports_stream = True - supports_gpt_35_turbo = True - supports_gpt_4 = True - - @staticmethod - def create_completion( - model: str, - messages: list[dict[str, str]], - stream: bool, **kwargs: Any) -> CreateResult: - - temperature = float(kwargs.get("temperature", 0.7)) - payload = { - "temperature": temperature, - "messages" : messages, - "model" : model, - "stream" : True, - } - - headers = { - "user-agent": "ChatX/39 CFNetwork/1408.0.4 Darwin/22.5.0", - } - response = requests.post("http://supertest.lockchat.app/v1/chat/completions", - json=payload, headers=headers, stream=True) - - response.raise_for_status() - for token in response.iter_lines(): - if b"The model: `gpt-4` does not exist" in token: - print("error, retrying...") - - Lockchat.create_completion( - model = model, - messages = messages, - stream = stream, - temperature = temperature, - **kwargs) - - if b"content" in token: - token = json.loads(token.decode("utf-8").split("data: ")[1]) - token = token["choices"][0]["delta"].get("content") - - if token: - yield (token) \ No newline at end of file diff --git a/g4f/Provider/deprecated/Myshell.py b/g4f/Provider/deprecated/Myshell.py deleted file mode 100644 index 2487440d..00000000 --- a/g4f/Provider/deprecated/Myshell.py +++ /dev/null @@ -1,165 +0,0 @@ -# not using WS anymore - -from __future__ import annotations - -import json, uuid, hashlib, time, random - -from aiohttp import ClientSession -from aiohttp.http import WSMsgType -import asyncio - -from ...typing import AsyncResult, Messages -from ..base_provider import AsyncGeneratorProvider, format_prompt - - -models = { - "samantha": "1e3be7fe89e94a809408b1154a2ee3e1", - "gpt-3.5-turbo": "8077335db7cd47e29f7de486612cc7fd", - "gpt-4": "01c8de4fbfc548df903712b0922a4e01", -} - - -class Myshell(AsyncGeneratorProvider): - url = "https://app.myshell.ai/chat" - working = False - supports_gpt_35_turbo = True - supports_gpt_4 = True - - @classmethod - async def create_async_generator( - cls, - model: str, - messages: Messages, - proxy: str = None, - timeout: int = 90, - **kwargs - ) -> AsyncResult: - if not model: - bot_id = models["samantha"] - elif model in models: - bot_id = models[model] - else: - raise ValueError(f"Model are not supported: {model}") - - user_agent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36' - visitor_id = generate_visitor_id(user_agent) - - async with ClientSession( - headers={'User-Agent': user_agent} - ) as session: - async with session.ws_connect( - "wss://api.myshell.ai/ws/?EIO=4&transport=websocket", - autoping=False, - timeout=timeout, - proxy=proxy - ) as wss: - # Send and receive hello message - await wss.receive_str() - message = json.dumps({"token": None, "visitorId": visitor_id}) - await wss.send_str(f"40/chat,{message}") - await wss.receive_str() - - # Fix "need_verify_captcha" issue - await asyncio.sleep(5) - - # Create chat message - text = format_prompt(messages) - chat_data = json.dumps(["text_chat",{ - "reqId": str(uuid.uuid4()), - "botUid": bot_id, - "sourceFrom": "myshellWebsite", - "text": text, - **generate_signature(text) - }]) - - # Send chat message - chat_start = "42/chat," - chat_message = f"{chat_start}{chat_data}" - await wss.send_str(chat_message) - - # Receive messages - async for message in wss: - if message.type != WSMsgType.TEXT: - continue - # Ping back - if message.data == "2": - await wss.send_str("3") - continue - # Is not chat message - if not message.data.startswith(chat_start): - continue - data_type, data = json.loads(message.data[len(chat_start):]) - if data_type == "text_stream": - if data["data"]["text"]: - yield data["data"]["text"] - elif data["data"]["isFinal"]: - break - elif data_type in ("message_replied", "need_verify_captcha"): - raise RuntimeError(f"Received unexpected message: {data_type}") - - -def generate_timestamp() -> str: - return str( - int( - str(int(time.time() * 1000))[:-1] - + str( - sum( - 2 * int(digit) - if idx % 2 == 0 - else 3 * int(digit) - for idx, digit in enumerate(str(int(time.time() * 1000))[:-1]) - ) - % 10 - ) - ) - ) - -def generate_signature(text: str): - timestamp = generate_timestamp() - version = 'v1.0.0' - secret = '8@VXGK3kKHr!u2gA' - data = f"{version}#{text}#{timestamp}#{secret}" - signature = hashlib.md5(data.encode()).hexdigest() - signature = signature[::-1] - return { - "signature": signature, - "timestamp": timestamp, - "version": version - } - -def xor_hash(B: str): - r = [] - i = 0 - - def o(e, t): - o_val = 0 - for i in range(len(t)): - o_val |= r[i] << (8 * i) - return e ^ o_val - - for e in range(len(B)): - t = ord(B[e]) - r.insert(0, 255 & t) - - if len(r) >= 4: - i = o(i, r) - r = [] - - if len(r) > 0: - i = o(i, r) - - return hex(i)[2:] - -def performance() -> str: - t = int(time.time() * 1000) - e = 0 - while t == int(time.time() * 1000): - e += 1 - return hex(t)[2:] + hex(e)[2:] - -def generate_visitor_id(user_agent: str) -> str: - f = performance() - r = hex(int(random.random() * (16**16)))[2:-2] - d = xor_hash(user_agent) - e = hex(1080 * 1920)[2:] - return f"{f}-{r}-{d}-{e}-{f}" \ No newline at end of file diff --git a/g4f/Provider/deprecated/NoowAi.py b/g4f/Provider/deprecated/NoowAi.py deleted file mode 100644 index dba87273..00000000 --- a/g4f/Provider/deprecated/NoowAi.py +++ /dev/null @@ -1,66 +0,0 @@ -from __future__ import annotations - -import json -from aiohttp import ClientSession - -from ..typing import AsyncResult, Messages -from .base_provider import AsyncGeneratorProvider -from .helper import get_random_string - -class NoowAi(AsyncGeneratorProvider): - url = "https://noowai.com" - supports_message_history = True - supports_gpt_35_turbo = True - working = False - - @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", - "Referer": f"{cls.url}/", - "Content-Type": "application/json", - "Origin": cls.url, - "Alt-Used": "noowai.com", - "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: - data = { - "botId": "default", - "customId": "d49bc3670c3d858458576d75c8ea0f5d", - "session": "N/A", - "chatId": get_random_string(), - "contextId": 25, - "messages": messages, - "newMessage": messages[-1]["content"], - "stream": True - } - async with session.post(f"{cls.url}/wp-json/mwai-ui/v1/chats/submit", json=data, proxy=proxy) as response: - response.raise_for_status() - async for line in response.content: - if line.startswith(b"data: "): - try: - line = json.loads(line[6:]) - assert "type" in line - except: - raise RuntimeError(f"Broken line: {line.decode()}") - if line["type"] == "live": - yield line["data"] - elif line["type"] == "end": - break - elif line["type"] == "error": - raise RuntimeError(line["data"]) \ No newline at end of file diff --git a/g4f/Provider/deprecated/Opchatgpts.py b/g4f/Provider/deprecated/Opchatgpts.py deleted file mode 100644 index 94b1d099..00000000 --- a/g4f/Provider/deprecated/Opchatgpts.py +++ /dev/null @@ -1,59 +0,0 @@ -from __future__ import annotations - -import random, string, json -from aiohttp import ClientSession - -from ...typing import Messages, AsyncResult -from ..base_provider import AsyncGeneratorProvider -from ..helper import get_random_string - -class Opchatgpts(AsyncGeneratorProvider): - url = "https://opchatgpts.net" - working = False - supports_message_history = True - supports_gpt_35_turbo = True - - @classmethod - async def create_async_generator( - cls, - model: str, - messages: Messages, - proxy: str = None, **kwargs) -> AsyncResult: - - headers = { - "User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36", - "Accept" : "*/*", - "Accept-Language" : "de,en-US;q=0.7,en;q=0.3", - "Origin" : cls.url, - "Alt-Used" : "opchatgpts.net", - "Referer" : f"{cls.url}/chatgpt-free-use/", - "Sec-Fetch-Dest" : "empty", - "Sec-Fetch-Mode" : "cors", - "Sec-Fetch-Site" : "same-origin", - } - async with ClientSession( - headers=headers - ) as session: - data = { - "botId": "default", - "chatId": get_random_string(), - "contextId": 28, - "customId": None, - "messages": messages, - "newMessage": messages[-1]["content"], - "session": "N/A", - "stream": True - } - async with session.post(f"{cls.url}/wp-json/mwai-ui/v1/chats/submit", json=data, proxy=proxy) as response: - response.raise_for_status() - async for line in response.content: - if line.startswith(b"data: "): - try: - line = json.loads(line[6:]) - assert "type" in line - except: - raise RuntimeError(f"Broken line: {line.decode()}") - if line["type"] == "live": - yield line["data"] - elif line["type"] == "end": - break \ No newline at end of file diff --git a/g4f/Provider/deprecated/OpenAssistant.py b/g4f/Provider/deprecated/OpenAssistant.py deleted file mode 100644 index 80cae3c2..00000000 --- a/g4f/Provider/deprecated/OpenAssistant.py +++ /dev/null @@ -1,88 +0,0 @@ -from __future__ import annotations - -import json - -from aiohttp import ClientSession - -from ...typing import AsyncResult, Messages -from ..base_provider import AsyncGeneratorProvider -from ..helper import format_prompt, get_cookies - -class OpenAssistant(AsyncGeneratorProvider): - url = "https://open-assistant.io/chat" - needs_auth = True - working = False - model = "OA_SFT_Llama_30B_6" - - @classmethod - async def create_async_generator( - cls, - model: str, - messages: Messages, - proxy: str = None, - cookies: dict = None, - **kwargs - ) -> AsyncResult: - if not cookies: - cookies = get_cookies("open-assistant.io") - - headers = { - 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36', - } - async with ClientSession( - cookies=cookies, - headers=headers - ) as session: - async with session.post("https://open-assistant.io/api/chat", proxy=proxy) as response: - chat_id = (await response.json())["id"] - - data = { - "chat_id": chat_id, - "content": f"[INST]\n{format_prompt(messages)}\n[/INST]", - "parent_id": None - } - async with session.post("https://open-assistant.io/api/chat/prompter_message", proxy=proxy, json=data) as response: - parent_id = (await response.json())["id"] - - data = { - "chat_id": chat_id, - "parent_id": parent_id, - "model_config_name": model if model else cls.model, - "sampling_parameters":{ - "top_k": 50, - "top_p": None, - "typical_p": None, - "temperature": 0.35, - "repetition_penalty": 1.1111111111111112, - "max_new_tokens": 1024, - **kwargs - }, - "plugins":[] - } - async with session.post("https://open-assistant.io/api/chat/assistant_message", proxy=proxy, json=data) as response: - data = await response.json() - if "id" in data: - message_id = data["id"] - elif "message" in data: - raise RuntimeError(data["message"]) - else: - response.raise_for_status() - - params = { - 'chat_id': chat_id, - 'message_id': message_id, - } - async with session.post("https://open-assistant.io/api/chat/events", proxy=proxy, params=params) as response: - start = "data: " - async for line in response.content: - line = line.decode("utf-8") - if line and line.startswith(start): - line = json.loads(line[len(start):]) - if line["event_type"] == "token": - yield line["text"] - - params = { - 'chat_id': chat_id, - } - async with session.delete("https://open-assistant.io/api/chat", proxy=proxy, params=params) as response: - response.raise_for_status() diff --git a/g4f/Provider/deprecated/Phind.py b/g4f/Provider/deprecated/Phind.py deleted file mode 100644 index c72bf09e..00000000 --- a/g4f/Provider/deprecated/Phind.py +++ /dev/null @@ -1,140 +0,0 @@ -from __future__ import annotations - -import re -import json -from urllib import parse -from datetime import datetime - -from ...typing import AsyncResult, Messages -from ..base_provider import AsyncGeneratorProvider -from ...requests import StreamSession - -class Phind(AsyncGeneratorProvider): - url = "https://www.phind.com" - working = False - lockdown = True - supports_stream = True - supports_message_history = True - - @classmethod - async def create_async_generator( - cls, - model: str, - messages: Messages, - proxy: str = None, - timeout: int = 120, - creative_mode: bool = False, - **kwargs - ) -> AsyncResult: - headers = { - "Accept": "*/*", - "Origin": cls.url, - "Referer": f"{cls.url}/search", - "Sec-Fetch-Dest": "empty", - "Sec-Fetch-Mode": "cors", - "Sec-Fetch-Site": "same-origin", - } - async with StreamSession( - headers=headers, - impersonate="chrome", - proxies={"https": proxy}, - timeout=timeout - ) as session: - url = "https://www.phind.com/search?home=true" - async with session.get(url) as response: - text = await response.text() - match = re.search(r'', text) - data = json.loads(match.group("json")) - challenge_seeds = data["props"]["pageProps"]["challengeSeeds"] - - prompt = messages[-1]["content"] - data = { - "question": prompt, - "question_history": [ - message["content"] for message in messages[:-1] if message["role"] == "user" - ], - "answer_history": [ - message["content"] for message in messages if message["role"] == "assistant" - ], - "webResults": [], - "options": { - "date": datetime.now().strftime("%d.%m.%Y"), - "language": "en-US", - "detailed": True, - "anonUserId": "", - "answerModel": "GPT-4" if model.startswith("gpt-4") else "Phind-34B", - "creativeMode": creative_mode, - "customLinks": [] - }, - "context": "\n".join([message["content"] for message in messages if message["role"] == "system"]), - } - data["challenge"] = generate_challenge(data, **challenge_seeds) - async with session.post(f"https://https.api.phind.com/infer/", headers=headers, json=data) as response: - new_line = False - async for line in response.iter_lines(): - if line.startswith(b"data: "): - chunk = line[6:] - if chunk.startswith(b''): - break - if chunk.startswith(b''): - raise RuntimeError(f"Response: {chunk.decode()}") - if chunk.startswith(b'') or chunk.startswith(b''): - pass - elif chunk.startswith(b"") or chunk.startswith(b""): - pass - elif chunk.startswith(b"") or chunk.startswith(b""): - pass - elif chunk: - yield chunk.decode() - elif new_line: - yield "\n" - new_line = False - else: - new_line = True - -def deterministic_stringify(obj): - def handle_value(value): - if isinstance(value, (dict, list)): - if isinstance(value, list): - return '[' + ','.join(sorted(map(handle_value, value))) + ']' - else: # It's a dict - return '{' + deterministic_stringify(value) + '}' - elif isinstance(value, bool): - return 'true' if value else 'false' - elif isinstance(value, (int, float)): - return format(value, '.8f').rstrip('0').rstrip('.') - elif isinstance(value, str): - return f'"{value}"' - else: - return 'null' - - items = sorted(obj.items(), key=lambda x: x[0]) - return ','.join([f'{k}:{handle_value(v)}' for k, v in items if handle_value(v) is not None]) - -def prng_general(seed, multiplier, addend, modulus): - a = seed * multiplier + addend - if a < 0: - return ((a%modulus)-modulus)/modulus - else: - return a%modulus/modulus - -def generate_challenge_seed(l): - I = deterministic_stringify(l) - d = parse.quote(I, safe='') - return simple_hash(d) - -def simple_hash(s): - d = 0 - for char in s: - if len(char) > 1 or ord(char) >= 256: - continue - d = ((d << 5) - d + ord(char[0])) & 0xFFFFFFFF - if d > 0x7FFFFFFF: # 2147483647 - d -= 0x100000000 # Subtract 2**32 - return d - -def generate_challenge(obj, **kwargs): - return prng_general( - seed=generate_challenge_seed(obj), - **kwargs - ) \ No newline at end of file diff --git a/g4f/Provider/deprecated/V50.py b/g4f/Provider/deprecated/V50.py deleted file mode 100644 index 456445f7..00000000 --- a/g4f/Provider/deprecated/V50.py +++ /dev/null @@ -1,61 +0,0 @@ -from __future__ import annotations - -import uuid - -import requests - -from ...typing import Any, CreateResult -from ..base_provider import AbstractProvider - - -class V50(AbstractProvider): - url = 'https://p5.v50.ltd' - supports_gpt_35_turbo = True - supports_stream = False - needs_auth = False - working = False - - @staticmethod - def create_completion( - model: str, - messages: list[dict[str, str]], - stream: bool, **kwargs: Any) -> CreateResult: - - conversation = ( - "\n".join( - f"{message['role']}: {message['content']}" for message in messages - ) - + "\nassistant: " - ) - payload = { - "prompt" : conversation, - "options" : {}, - "systemMessage" : ".", - "temperature" : kwargs.get("temperature", 0.4), - "top_p" : kwargs.get("top_p", 0.4), - "model" : model, - "user" : str(uuid.uuid4()) - } - - headers = { - 'authority' : 'p5.v50.ltd', - 'accept' : 'application/json, text/plain, */*', - 'accept-language' : 'id-ID,id;q=0.9,en-US;q=0.8,en;q=0.7', - 'content-type' : 'application/json', - 'origin' : 'https://p5.v50.ltd', - 'referer' : 'https://p5.v50.ltd/', - 'sec-ch-ua-platform': '"Windows"', - 'sec-fetch-dest' : 'empty', - 'sec-fetch-mode' : 'cors', - 'sec-fetch-site' : 'same-origin', - 'user-agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36' - } - response = requests.post( - "https://p5.v50.ltd/api/chat-process", - json=payload, - headers=headers, - proxies=kwargs.get('proxy', {}), - ) - - if "https://fk1.v50.ltd" not in response.text: - yield response.text \ No newline at end of file diff --git a/g4f/Provider/deprecated/Vercel.py b/g4f/Provider/deprecated/Vercel.py deleted file mode 100644 index adf7b208..00000000 --- a/g4f/Provider/deprecated/Vercel.py +++ /dev/null @@ -1,392 +0,0 @@ -from __future__ import annotations - -import json, base64, requests, random, uuid - -try: - import execjs - has_requirements = True -except ImportError: - has_requirements = False - -from ...typing import Messages, TypedDict, CreateResult, Any -from ..base_provider import AbstractProvider -from ...errors import MissingRequirementsError - -class Vercel(AbstractProvider): - url = 'https://sdk.vercel.ai' - working = False - supports_message_history = True - supports_gpt_35_turbo = True - supports_stream = True - - @staticmethod - def create_completion( - model: str, - messages: Messages, - stream: bool, - proxy: str = None, - **kwargs - ) -> CreateResult: - if not has_requirements: - raise MissingRequirementsError('Install "PyExecJS" package') - - if not model: - model = "gpt-3.5-turbo" - elif model not in model_info: - raise ValueError(f"Vercel does not support {model}") - - 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', - 'content-type': 'application/json', - 'custom-encoding': get_anti_bot_token(), - 'origin': 'https://sdk.vercel.ai', - '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', - } - - json_data = { - 'model' : model_info[model]['id'], - 'messages' : messages, - 'playgroundId': str(uuid.uuid4()), - 'chatIndex' : 0, - **model_info[model]['default_params'], - **kwargs - } - - max_retries = kwargs.get('max_retries', 20) - for _ in range(max_retries): - response = requests.post('https://chat.vercel.ai/api/chat', - headers=headers, json=json_data, stream=True, proxies={"https": proxy}) - try: - response.raise_for_status() - except: - continue - for token in response.iter_content(chunk_size=None): - yield token.decode() - break - - -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://sdk.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 `${this}`}; - return (%s)(%s)''' % (raw_data['c'], raw_data['a']) - - raw_token = json.dumps({'r': execjs.compile(js_script).call(''), 't': raw_data['t']}, - separators = (",", ":")) - - return base64.b64encode(raw_token.encode('utf-16le')).decode() - -class ModelInfo(TypedDict): - id: str - default_params: dict[str, Any] - -model_info: dict[str, ModelInfo] = { - # 'claude-instant-v1': { - # 'id': 'anthropic:claude-instant-v1', - # 'default_params': { - # 'temperature': 1, - # 'maximumLength': 1024, - # 'topP': 1, - # 'topK': 1, - # 'presencePenalty': 1, - # 'frequencyPenalty': 1, - # 'stopSequences': ['\n\nHuman:'], - # }, - # }, - # 'claude-v1': { - # 'id': 'anthropic:claude-v1', - # 'default_params': { - # 'temperature': 1, - # 'maximumLength': 1024, - # 'topP': 1, - # 'topK': 1, - # 'presencePenalty': 1, - # 'frequencyPenalty': 1, - # 'stopSequences': ['\n\nHuman:'], - # }, - # }, - # 'claude-v2': { - # 'id': 'anthropic:claude-v2', - # 'default_params': { - # 'temperature': 1, - # 'maximumLength': 1024, - # 'topP': 1, - # 'topK': 1, - # 'presencePenalty': 1, - # 'frequencyPenalty': 1, - # 'stopSequences': ['\n\nHuman:'], - # }, - # }, - 'replicate/llama70b-v2-chat': { - 'id': 'replicate:replicate/llama-2-70b-chat', - 'default_params': { - 'temperature': 0.75, - 'maximumLength': 3000, - 'topP': 1, - 'repetitionPenalty': 1, - }, - }, - 'a16z-infra/llama7b-v2-chat': { - 'id': 'replicate:a16z-infra/llama7b-v2-chat', - 'default_params': { - 'temperature': 0.75, - 'maximumLength': 3000, - 'topP': 1, - 'repetitionPenalty': 1, - }, - }, - 'a16z-infra/llama13b-v2-chat': { - 'id': 'replicate:a16z-infra/llama13b-v2-chat', - 'default_params': { - 'temperature': 0.75, - 'maximumLength': 3000, - 'topP': 1, - 'repetitionPenalty': 1, - }, - }, - 'replicate/llama-2-70b-chat': { - 'id': 'replicate:replicate/llama-2-70b-chat', - 'default_params': { - 'temperature': 0.75, - 'maximumLength': 3000, - 'topP': 1, - 'repetitionPenalty': 1, - }, - }, - 'bigscience/bloom': { - 'id': 'huggingface:bigscience/bloom', - 'default_params': { - 'temperature': 0.5, - 'maximumLength': 1024, - 'topP': 0.95, - 'topK': 4, - 'repetitionPenalty': 1.03, - }, - }, - 'google/flan-t5-xxl': { - 'id': 'huggingface:google/flan-t5-xxl', - 'default_params': { - 'temperature': 0.5, - 'maximumLength': 1024, - 'topP': 0.95, - 'topK': 4, - 'repetitionPenalty': 1.03, - }, - }, - 'EleutherAI/gpt-neox-20b': { - 'id': 'huggingface:EleutherAI/gpt-neox-20b', - 'default_params': { - 'temperature': 0.5, - 'maximumLength': 1024, - 'topP': 0.95, - 'topK': 4, - 'repetitionPenalty': 1.03, - 'stopSequences': [], - }, - }, - 'OpenAssistant/oasst-sft-4-pythia-12b-epoch-3.5': { - 'id': 'huggingface:OpenAssistant/oasst-sft-4-pythia-12b-epoch-3.5', - 'default_params': { - 'maximumLength': 1024, - 'typicalP': 0.2, - 'repetitionPenalty': 1, - }, - }, - 'OpenAssistant/oasst-sft-1-pythia-12b': { - 'id': 'huggingface:OpenAssistant/oasst-sft-1-pythia-12b', - 'default_params': { - 'maximumLength': 1024, - 'typicalP': 0.2, - 'repetitionPenalty': 1, - }, - }, - 'bigcode/santacoder': { - 'id': 'huggingface:bigcode/santacoder', - 'default_params': { - 'temperature': 0.5, - 'maximumLength': 1024, - 'topP': 0.95, - 'topK': 4, - 'repetitionPenalty': 1.03, - }, - }, - 'command-light-nightly': { - 'id': 'cohere:command-light-nightly', - 'default_params': { - 'temperature': 0.9, - 'maximumLength': 1024, - 'topP': 1, - 'topK': 0, - 'presencePenalty': 0, - 'frequencyPenalty': 0, - 'stopSequences': [], - }, - }, - 'command-nightly': { - 'id': 'cohere:command-nightly', - 'default_params': { - 'temperature': 0.9, - 'maximumLength': 1024, - 'topP': 1, - 'topK': 0, - 'presencePenalty': 0, - 'frequencyPenalty': 0, - 'stopSequences': [], - }, - }, - # 'gpt-4': { - # 'id': 'openai:gpt-4', - # 'default_params': { - # 'temperature': 0.7, - # 'maximumLength': 8192, - # 'topP': 1, - # 'presencePenalty': 0, - # 'frequencyPenalty': 0, - # 'stopSequences': [], - # }, - # }, - # 'gpt-4-0613': { - # 'id': 'openai:gpt-4-0613', - # 'default_params': { - # 'temperature': 0.7, - # 'maximumLength': 8192, - # 'topP': 1, - # 'presencePenalty': 0, - # 'frequencyPenalty': 0, - # 'stopSequences': [], - # }, - # }, - 'code-davinci-002': { - 'id': 'openai:code-davinci-002', - 'default_params': { - 'temperature': 0.5, - 'maximumLength': 1024, - 'topP': 1, - 'presencePenalty': 0, - 'frequencyPenalty': 0, - 'stopSequences': [], - }, - }, - 'gpt-3.5-turbo': { - 'id': 'openai:gpt-3.5-turbo', - 'default_params': { - 'temperature': 0.7, - 'maximumLength': 4096, - 'topP': 1, - 'topK': 1, - 'presencePenalty': 1, - 'frequencyPenalty': 1, - 'stopSequences': [], - }, - }, - 'gpt-3.5-turbo-16k': { - 'id': 'openai:gpt-3.5-turbo-16k', - 'default_params': { - 'temperature': 0.7, - 'maximumLength': 16280, - 'topP': 1, - 'topK': 1, - 'presencePenalty': 1, - 'frequencyPenalty': 1, - 'stopSequences': [], - }, - }, - 'gpt-3.5-turbo-16k-0613': { - 'id': 'openai:gpt-3.5-turbo-16k-0613', - 'default_params': { - 'temperature': 0.7, - 'maximumLength': 16280, - 'topP': 1, - 'topK': 1, - 'presencePenalty': 1, - 'frequencyPenalty': 1, - 'stopSequences': [], - }, - }, - 'text-ada-001': { - 'id': 'openai:text-ada-001', - 'default_params': { - 'temperature': 0.5, - 'maximumLength': 1024, - 'topP': 1, - 'presencePenalty': 0, - 'frequencyPenalty': 0, - 'stopSequences': [], - }, - }, - 'text-babbage-001': { - 'id': 'openai:text-babbage-001', - 'default_params': { - 'temperature': 0.5, - 'maximumLength': 1024, - 'topP': 1, - 'presencePenalty': 0, - 'frequencyPenalty': 0, - 'stopSequences': [], - }, - }, - 'text-curie-001': { - 'id': 'openai:text-curie-001', - 'default_params': { - 'temperature': 0.5, - 'maximumLength': 1024, - 'topP': 1, - 'presencePenalty': 0, - 'frequencyPenalty': 0, - 'stopSequences': [], - }, - }, - 'text-davinci-002': { - 'id': 'openai:text-davinci-002', - 'default_params': { - 'temperature': 0.5, - 'maximumLength': 1024, - 'topP': 1, - 'presencePenalty': 0, - 'frequencyPenalty': 0, - 'stopSequences': [], - }, - }, - 'text-davinci-003': { - 'id': 'openai:text-davinci-003', - 'default_params': { - 'temperature': 0.5, - 'maximumLength': 4097, - 'topP': 1, - 'presencePenalty': 0, - 'frequencyPenalty': 0, - 'stopSequences': [], - }, - }, -} \ No newline at end of file diff --git a/g4f/Provider/deprecated/Vitalentum.py b/g4f/Provider/deprecated/Vitalentum.py deleted file mode 100644 index 8f466a52..00000000 --- a/g4f/Provider/deprecated/Vitalentum.py +++ /dev/null @@ -1,55 +0,0 @@ -from __future__ import annotations - -import json -from aiohttp import ClientSession - -from ..base_provider import AsyncGeneratorProvider -from ...typing import AsyncResult, Messages - -class Vitalentum(AsyncGeneratorProvider): - url = "https://app.vitalentum.io" - supports_gpt_35_turbo = True - - - @classmethod - async def create_async_generator( - cls, - model: str, - messages: Messages, - proxy: str = None, - **kwargs - ) -> AsyncResult: - headers = { - "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36", - "Accept": "text/event-stream", - "Accept-language": "de,en-US;q=0.7,en;q=0.3", - "Origin": cls.url, - "Referer": f"{cls.url}/", - "Sec-Fetch-Dest": "empty", - "Sec-Fetch-Mode": "cors", - "Sec-Fetch-Site": "same-origin", - } - conversation = json.dumps({"history": [{ - "speaker": "human" if message["role"] == "user" else "bot", - "text": message["content"], - } for message in messages]}) - data = { - "conversation": conversation, - "temperature": 0.7, - **kwargs - } - async with ClientSession( - headers=headers - ) as session: - async with session.post(f"{cls.url}/api/converse-edge", json=data, proxy=proxy) as response: - response.raise_for_status() - async for line in response.content: - line = line.decode() - if line.startswith("data: "): - if line.startswith("data: [DONE]"): - break - line = json.loads(line[6:-1]) - content = line["choices"][0]["delta"].get("content") - - if content: - yield content \ No newline at end of file diff --git a/g4f/Provider/deprecated/VoiGpt.py b/g4f/Provider/deprecated/VoiGpt.py deleted file mode 100644 index 9b061e63..00000000 --- a/g4f/Provider/deprecated/VoiGpt.py +++ /dev/null @@ -1,91 +0,0 @@ -from __future__ import annotations - -import json -import requests -from ..base_provider import AbstractProvider -from ...typing import Messages, CreateResult - - -class VoiGpt(AbstractProvider): - """ - VoiGpt - A provider for VoiGpt.com - - **Note** : to use this provider you have to get your csrf token/cookie from the voigpt.com website - - Args: - model: The model to use - messages: The messages to send - stream: Whether to stream the response - proxy: The proxy to use - access_token: The access token to use - **kwargs: Additional keyword arguments - - Returns: - A CreateResult object - """ - url = "https://voigpt.com" - working = False - supports_gpt_35_turbo = True - supports_message_history = True - supports_stream = False - _access_token: str = None - - @classmethod - def create_completion( - cls, - model: str, - messages: Messages, - stream: bool, - proxy: str = None, - access_token: str = None, - **kwargs - ) -> CreateResult: - - if not model: - model = "gpt-3.5-turbo" - if not access_token: - access_token = cls._access_token - if not access_token: - headers = { - "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", - "accept-language": "de-DE,de;q=0.9,en-DE;q=0.8,en;q=0.7,en-US;q=0.6", - "sec-ch-ua": "\"Google Chrome\";v=\"119\", \"Chromium\";v=\"119\", \"Not?A_Brand\";v=\"24\"", - "sec-ch-ua-mobile": "?0", - "sec-ch-ua-platform": "\"Linux\"", - "sec-fetch-dest": "document", - "sec-fetch-mode": "navigate", - "sec-fetch-site": "none", - "sec-fetch-user": "?1", - "upgrade-insecure-requests": "1", - "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36", - } - req_response = requests.get(cls.url, headers=headers) - access_token = cls._access_token = req_response.cookies.get("csrftoken") - - headers = { - "Accept-Encoding": "gzip, deflate, br", - "Accept-Language": "de-DE,de;q=0.9,en-DE;q=0.8,en;q=0.7,en-US;q=0.6", - "Cookie": f"csrftoken={access_token};", - "Origin": "https://voigpt.com", - "Referer": "https://voigpt.com/", - "Sec-Ch-Ua": "'Google Chrome';v='119', 'Chromium';v='119', 'Not?A_Brand';v='24'", - "Sec-Ch-Ua-Mobile": "?0", - "Sec-Ch-Ua-Platform": "'Windows'", - "Sec-Fetch-Dest": "empty", - "Sec-Fetch-Mode": "cors", - "Sec-Fetch-Site": "same-origin", - "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36", - "X-Csrftoken": access_token, - } - - payload = { - "messages": messages, - } - request_url = f"{cls.url}/generate_response/" - req_response = requests.post(request_url, headers=headers, json=payload) - try: - response = json.loads(req_response.text) - yield response["response"] - except: - raise RuntimeError(f"Response: {req_response.text}") - diff --git a/g4f/Provider/deprecated/Wewordle.py b/g4f/Provider/deprecated/Wewordle.py deleted file mode 100644 index c30887fb..00000000 --- a/g4f/Provider/deprecated/Wewordle.py +++ /dev/null @@ -1,65 +0,0 @@ -from __future__ import annotations - -import random, string, time -from aiohttp import ClientSession - -from ..base_provider import AsyncProvider - - -class Wewordle(AsyncProvider): - url = "https://wewordle.org" - working = False - supports_gpt_35_turbo = True - - @classmethod - async def create_async( - cls, - model: str, - messages: list[dict[str, str]], - proxy: str = None, - **kwargs - ) -> str: - - headers = { - "accept" : "*/*", - "pragma" : "no-cache", - "Content-Type" : "application/json", - "Connection" : "keep-alive" - } - - _user_id = "".join(random.choices(f"{string.ascii_lowercase}{string.digits}", k=16)) - _app_id = "".join(random.choices(f"{string.ascii_lowercase}{string.digits}", k=31)) - _request_date = time.strftime("%Y-%m-%dT%H:%M:%S.000Z", time.gmtime()) - data = { - "user" : _user_id, - "messages" : messages, - "subscriber": { - "originalPurchaseDate" : None, - "originalApplicationVersion" : None, - "allPurchaseDatesMillis" : {}, - "entitlements" : {"active": {}, "all": {}}, - "allPurchaseDates" : {}, - "allExpirationDatesMillis" : {}, - "allExpirationDates" : {}, - "originalAppUserId" : f"$RCAnonymousID:{_app_id}", - "latestExpirationDate" : None, - "requestDate" : _request_date, - "latestExpirationDateMillis" : None, - "nonSubscriptionTransactions" : [], - "originalPurchaseDateMillis" : None, - "managementURL" : None, - "allPurchasedProductIdentifiers": [], - "firstSeen" : _request_date, - "activeSubscriptions" : [], - } - } - - - async with ClientSession( - headers=headers - ) as session: - async with session.post(f"{cls.url}/gptapi/v1/android/turbo", proxy=proxy, json=data) as response: - response.raise_for_status() - content = (await response.json())["message"]["content"] - if content: - return content \ No newline at end of file diff --git a/g4f/Provider/deprecated/Wuguokai.py b/g4f/Provider/deprecated/Wuguokai.py deleted file mode 100644 index f12d1bfe..00000000 --- a/g4f/Provider/deprecated/Wuguokai.py +++ /dev/null @@ -1,57 +0,0 @@ -from __future__ import annotations - -import random - -import requests - -from ...typing import Any, CreateResult -from ..base_provider import AbstractProvider, format_prompt - - -class Wuguokai(AbstractProvider): - url = 'https://chat.wuguokai.xyz' - supports_gpt_35_turbo = True - working = False - - @staticmethod - def create_completion( - model: str, - messages: list[dict[str, str]], - stream: bool, - **kwargs: Any, - ) -> CreateResult: - headers = { - 'authority': 'ai-api.wuguokai.xyz', - 'accept': 'application/json, text/plain, */*', - 'accept-language': 'id-ID,id;q=0.9,en-US;q=0.8,en;q=0.7', - 'content-type': 'application/json', - 'origin': 'https://chat.wuguokai.xyz', - 'referer': 'https://chat.wuguokai.xyz/', - 'sec-ch-ua': '"Not.A/Brand";v="8", "Chromium";v="114", "Google Chrome";v="114"', - 'sec-ch-ua-mobile': '?0', - 'sec-ch-ua-platform': '"Windows"', - 'sec-fetch-dest': 'empty', - 'sec-fetch-mode': 'cors', - 'sec-fetch-site': 'same-site', - 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36' - } - data ={ - "prompt": format_prompt(messages), - "options": {}, - "userId": f"#/chat/{random.randint(1,99999999)}", - "usingContext": True - } - response = requests.post( - "https://ai-api20.wuguokai.xyz/api/chat-process", - headers=headers, - timeout=3, - json=data, - proxies=kwargs.get('proxy', {}), - ) - _split = response.text.split("> 若回答失败请重试或多刷新几次界面后重试") - if response.status_code != 200: - raise Exception(f"Error: {response.status_code} {response.reason}") - if len(_split) > 1: - yield _split[1].strip() - else: - yield _split[0].strip() \ No newline at end of file diff --git a/g4f/Provider/deprecated/Ylokh.py b/g4f/Provider/deprecated/Ylokh.py deleted file mode 100644 index dbff4602..00000000 --- a/g4f/Provider/deprecated/Ylokh.py +++ /dev/null @@ -1,58 +0,0 @@ -from __future__ import annotations - -import json - -from ...requests import StreamSession -from ..base_provider import AsyncGeneratorProvider -from ...typing import AsyncResult, Messages - -class Ylokh(AsyncGeneratorProvider): - url = "https://chat.ylokh.xyz" - working = False - supports_message_history = True - supports_gpt_35_turbo = True - - - @classmethod - async def create_async_generator( - cls, - model: str, - messages: Messages, - stream: bool = True, - proxy: str = None, - timeout: int = 120, - **kwargs - ) -> AsyncResult: - model = model if model else "gpt-3.5-turbo" - headers = {"Origin": cls.url, "Referer": f"{cls.url}/"} - data = { - "messages": messages, - "model": model, - "temperature": 1, - "presence_penalty": 0, - "top_p": 1, - "frequency_penalty": 0, - "allow_fallback": True, - "stream": stream, - **kwargs - } - async with StreamSession( - headers=headers, - proxies={"https": proxy}, - timeout=timeout - ) as session: - async with session.post("https://chatapi.ylokh.xyz/v1/chat/completions", json=data) as response: - response.raise_for_status() - if stream: - async for line in response.iter_lines(): - line = line.decode() - if line.startswith("data: "): - if line.startswith("data: [DONE]"): - break - line = json.loads(line[6:]) - content = line["choices"][0]["delta"].get("content") - if content: - yield content - else: - chat = await response.json() - yield chat["choices"][0]["message"].get("content") \ No newline at end of file diff --git a/g4f/Provider/deprecated/Yqcloud.py b/g4f/Provider/deprecated/Yqcloud.py deleted file mode 100644 index 227f8995..00000000 --- a/g4f/Provider/deprecated/Yqcloud.py +++ /dev/null @@ -1,61 +0,0 @@ -from __future__ import annotations - -import random -from ...requests import StreamSession - -from ...typing import AsyncResult, Messages -from ..base_provider import AsyncGeneratorProvider, format_prompt - - -class Yqcloud(AsyncGeneratorProvider): - url = "https://chat9.yqcloud.top/" - working = False - supports_gpt_35_turbo = True - - @staticmethod - async def create_async_generator( - model: str, - messages: Messages, - proxy: str = None, - timeout: int = 120, - **kwargs, - ) -> AsyncResult: - async with StreamSession( - headers=_create_header(), proxies={"https": proxy}, timeout=timeout - ) as session: - payload = _create_payload(messages, **kwargs) - async with session.post("https://api.aichatos.cloud/api/generateStream", json=payload) as response: - response.raise_for_status() - async for chunk in response.iter_content(): - if chunk: - chunk = chunk.decode() - if "sorry, 您的ip已由于触发防滥用检测而被封禁" in chunk: - raise RuntimeError("IP address is blocked by abuse detection.") - yield chunk - - -def _create_header(): - return { - "accept" : "application/json, text/plain, */*", - "content-type" : "application/json", - "origin" : "https://chat9.yqcloud.top", - "referer" : "https://chat9.yqcloud.top/" - } - - -def _create_payload( - messages: Messages, - system_message: str = "", - user_id: int = None, - **kwargs -): - if not user_id: - user_id = random.randint(1690000544336, 2093025544336) - return { - "prompt": format_prompt(messages), - "network": True, - "system": system_message, - "withoutContext": False, - "stream": True, - "userId": f"#/chat/{user_id}" - } diff --git a/g4f/Provider/deprecated/__init__.py b/g4f/Provider/deprecated/__init__.py deleted file mode 100644 index bf923f2a..00000000 --- a/g4f/Provider/deprecated/__init__.py +++ /dev/null @@ -1,35 +0,0 @@ -from .AiService import AiService -from .CodeLinkAva import CodeLinkAva -from .DfeHub import DfeHub -from .EasyChat import EasyChat -from .Forefront import Forefront -from .GetGpt import GetGpt -from .Lockchat import Lockchat -from .Wewordle import Wewordle -from .Equing import Equing -from .Wuguokai import Wuguokai -from .V50 import V50 -from .FastGpt import FastGpt -from .Aivvm import Aivvm -from .Vitalentum import Vitalentum -from .H2o import H2o -from .Myshell import Myshell -from .Acytoo import Acytoo -from .Aibn import Aibn -from .Ails import Ails -from .ChatgptDuo import ChatgptDuo -from .Cromicle import Cromicle -from .Opchatgpts import Opchatgpts -from .Yqcloud import Yqcloud -from .Aichat import Aichat -from .Berlin import Berlin -from .Phind import Phind -from .AiAsk import AiAsk -from ..AiChatOnline import AiChatOnline -from .ChatAnywhere import ChatAnywhere -from .FakeGpt import FakeGpt -from .GeekGpt import GeekGpt -from .GPTalk import GPTalk -from .Hashnode import Hashnode -from .Ylokh import Ylokh -from .OpenAssistant import OpenAssistant \ No newline at end of file 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/selenium/Bard.py b/g4f/Provider/selenium/Bard.py deleted file mode 100644 index 9c809128..00000000 --- a/g4f/Provider/selenium/Bard.py +++ /dev/null @@ -1,80 +0,0 @@ -from __future__ import annotations - -import time -import os - -try: - from selenium.webdriver.common.by import By - from selenium.webdriver.support.ui import WebDriverWait - from selenium.webdriver.support import expected_conditions as EC -except ImportError: - pass - -from ...typing import CreateResult, Messages -from ..base_provider import AbstractProvider -from ..helper import format_prompt -from ...webdriver import WebDriver, WebDriverSession, element_send_text - - -class Bard(AbstractProvider): - url = "https://bard.google.com" - working = False - needs_auth = True - webdriver = True - - @classmethod - def create_completion( - cls, - model: str, - messages: Messages, - stream: bool, - proxy: str = None, - webdriver: WebDriver = None, - user_data_dir: str = None, - headless: bool = True, - **kwargs - ) -> CreateResult: - prompt = format_prompt(messages) - session = WebDriverSession(webdriver, user_data_dir, headless, proxy=proxy) - with session as driver: - try: - driver.get(f"{cls.url}/chat") - wait = WebDriverWait(driver, 10 if headless else 240) - wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "div.ql-editor.textarea"))) - except: - # Reopen browser for login - if not webdriver: - driver = session.reopen() - driver.get(f"{cls.url}/chat") - login_url = os.environ.get("G4F_LOGIN_URL") - if login_url: - yield f"Please login: [Google Bard]({login_url})\n\n" - wait = WebDriverWait(driver, 240) - wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "div.ql-editor.textarea"))) - else: - raise RuntimeError("Prompt textarea not found. You may not be logged in.") - - # Add hook in XMLHttpRequest - script = """ -const _http_request_open = XMLHttpRequest.prototype.open; -window._message = ""; -XMLHttpRequest.prototype.open = function(method, url) { - if (url.includes("/assistant.lamda.BardFrontendService/StreamGenerate")) { - this.addEventListener("load", (event) => { - window._message = JSON.parse(JSON.parse(this.responseText.split("\\n")[3])[0][2])[4][0][1][0]; - }); - } - return _http_request_open.call(this, method, url); -} -""" - driver.execute_script(script) - - element_send_text(driver.find_element(By.CSS_SELECTOR, "div.ql-editor.textarea"), prompt) - - while True: - chunk = driver.execute_script("return window._message;") - if chunk: - yield chunk - return - else: - time.sleep(0.1) \ No newline at end of file diff --git a/g4f/Provider/selenium/MyShell.py b/g4f/Provider/selenium/MyShell.py index a3f246ff..02e182d4 100644 --- a/g4f/Provider/selenium/MyShell.py +++ b/g4f/Provider/selenium/MyShell.py @@ -9,7 +9,7 @@ from ...webdriver import WebDriver, WebDriverSession, bypass_cloudflare class MyShell(AbstractProvider): url = "https://app.myshell.ai/chat" - working = True + working = False supports_gpt_35_turbo = True supports_stream = True @@ -73,4 +73,4 @@ return content; elif chunk != "": break else: - time.sleep(0.1) \ No newline at end of file + time.sleep(0.1) diff --git a/g4f/Provider/selenium/PerplexityAi.py b/g4f/Provider/selenium/PerplexityAi.py index 6b529d5b..d965dbf7 100644 --- a/g4f/Provider/selenium/PerplexityAi.py +++ b/g4f/Provider/selenium/PerplexityAi.py @@ -16,7 +16,7 @@ from ...webdriver import WebDriver, WebDriverSession, element_send_text class PerplexityAi(AbstractProvider): url = "https://www.perplexity.ai" - working = True + working = False supports_gpt_35_turbo = True supports_stream = True @@ -105,4 +105,4 @@ if(window._message && window._message != window._last_message) { elif chunk != "": break else: - time.sleep(0.1) \ No newline at end of file + time.sleep(0.1) diff --git a/g4f/Provider/selenium/TalkAi.py b/g4f/Provider/selenium/TalkAi.py index 89280598..a7b63375 100644 --- a/g4f/Provider/selenium/TalkAi.py +++ b/g4f/Provider/selenium/TalkAi.py @@ -8,7 +8,7 @@ from ...webdriver import WebDriver, WebDriverSession class TalkAi(AbstractProvider): url = "https://talkai.info" - working = True + working = False supports_gpt_35_turbo = True supports_stream = True @@ -83,4 +83,4 @@ return content; elif chunk != "": break else: - time.sleep(0.1) \ No newline at end of file + time.sleep(0.1) diff --git a/g4f/Provider/selenium/__init__.py b/g4f/Provider/selenium/__init__.py index 1b801725..3a59ea58 100644 --- a/g4f/Provider/selenium/__init__.py +++ b/g4f/Provider/selenium/__init__.py @@ -2,4 +2,3 @@ from .MyShell import MyShell from .PerplexityAi import PerplexityAi from .Phind import Phind from .TalkAi import TalkAi -from .Bard import Bard \ No newline at end of file diff --git a/g4f/Provider/unfinished/AiChatting.py b/g4f/Provider/unfinished/AiChatting.py deleted file mode 100644 index f062fa98..00000000 --- a/g4f/Provider/unfinished/AiChatting.py +++ /dev/null @@ -1,66 +0,0 @@ -from __future__ import annotations - -from urllib.parse import unquote - -from ...typing import AsyncResult, Messages -from ..base_provider import AbstractProvider -from ...webdriver import WebDriver -from ...requests import Session, get_session_from_browser - -class AiChatting(AbstractProvider): - url = "https://www.aichatting.net" - supports_gpt_35_turbo = True - _session: Session = None - - @classmethod - def create_completion( - cls, - model: str, - messages: Messages, - stream: bool, - proxy: str = None, - timeout: int = 120, - webdriver: WebDriver = None, - **kwargs - ) -> AsyncResult: - if not cls._session: - cls._session = get_session_from_browser(cls.url, webdriver, proxy, timeout) - visitorId = unquote(cls._session.cookies.get("aichatting.website.visitorId")) - - headers = { - "accept": "application/json, text/plain, */*", - "lang": "en", - "source": "web" - } - data = { - "roleId": 0, - } - try: - response = cls._session.post("https://aga-api.aichatting.net/aigc/chat/record/conversation/create", json=data, headers=headers) - response.raise_for_status() - conversation_id = response.json()["data"]["conversationId"] - except Exception as e: - cls.reset() - raise e - headers = { - "authority": "aga-api.aichatting.net", - "accept": "text/event-stream,application/json, text/event-stream", - "lang": "en", - "source": "web", - "vtoken": visitorId, - } - data = { - "spaceHandle": True, - "roleId": 0, - "messages": messages, - "conversationId": conversation_id, - } - response = cls._session.post("https://aga-api.aichatting.net/aigc/chat/v2/stream", json=data, headers=headers, stream=True) - response.raise_for_status() - for chunk in response.iter_lines(): - if chunk.startswith(b"data:"): - yield chunk[5:].decode().replace("-=- --", " ").replace("-=-n--", "\n").replace("--@DONE@--", "") - - @classmethod - def reset(cls): - cls._session = None \ No newline at end of file diff --git a/g4f/Provider/unfinished/ChatAiGpt.py b/g4f/Provider/unfinished/ChatAiGpt.py deleted file mode 100644 index bc962623..00000000 --- a/g4f/Provider/unfinished/ChatAiGpt.py +++ /dev/null @@ -1,68 +0,0 @@ -from __future__ import annotations - -import re -from aiohttp import ClientSession - -from ...typing import AsyncResult, Messages -from ..base_provider import AsyncGeneratorProvider -from ..helper import format_prompt - - -class ChatAiGpt(AsyncGeneratorProvider): - url = "https://chataigpt.org" - supports_gpt_35_turbo = True - _nonce = None - _post_id = None - - @classmethod - async def create_async_generator( - cls, - model: str, - messages: Messages, - proxy: str = None, - **kwargs - ) -> AsyncResult: - headers = { - "User-Agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/118.0", - "Accept": "*/*", - "Accept-Language": "de,en-US;q=0.7,en;q=0.3", - "Accept-Encoding": "gzip, deflate, br", - "Origin": cls.url, - "Alt-Used": cls.url, - "Connection": "keep-alive", - "Referer": cls.url, - "Pragma": "no-cache", - "Cache-Control": "no-cache", - "TE": "trailers", - "Sec-Fetch-Dest": "empty", - "Sec-Fetch-Mode": "cors", - "Sec-Fetch-Site": "same-origin", - } - async with ClientSession(headers=headers) as session: - if not cls._nonce: - async with session.get(f"{cls.url}/", proxy=proxy) as response: - response.raise_for_status() - response = await response.text() - - result = re.search( - r'data-nonce=(.*?) data-post-id=([0-9]+)', response - ) - - if result: - cls._nonce, cls._post_id = result.group(1), result.group(2) - else: - raise RuntimeError("No nonce found") - prompt = format_prompt(messages) - data = { - "_wpnonce": cls._nonce, - "post_id": cls._post_id, - "url": cls.url, - "action": "wpaicg_chat_shortcode_message", - "message": prompt, - "bot_id": 0 - } - async with session.post(f"{cls.url}/wp-admin/admin-ajax.php", data=data, proxy=proxy) as response: - response.raise_for_status() - async for chunk in response.content: - if chunk: - yield chunk.decode() \ No newline at end of file diff --git a/g4f/Provider/unfinished/Komo.py b/g4f/Provider/unfinished/Komo.py deleted file mode 100644 index 84d8d634..00000000 --- a/g4f/Provider/unfinished/Komo.py +++ /dev/null @@ -1,44 +0,0 @@ -from __future__ import annotations - -import json - -from ...requests import StreamSession -from ...typing import AsyncGenerator -from ..base_provider import AsyncGeneratorProvider, format_prompt - -class Komo(AsyncGeneratorProvider): - url = "https://komo.ai/api/ask" - supports_gpt_35_turbo = True - - @classmethod - async def create_async_generator( - cls, - model: str, - messages: list[dict[str, str]], - **kwargs - ) -> AsyncGenerator: - async with StreamSession(impersonate="chrome107") as session: - prompt = format_prompt(messages) - data = { - "query": prompt, - "FLAG_URLEXTRACT": "false", - "token": "", - "FLAG_MODELA": "1", - } - headers = { - 'authority': 'komo.ai', - 'accept': 'text/event-stream', - 'cache-control': 'no-cache', - 'referer': 'https://komo.ai/', - } - - async with session.get(cls.url, params=data, headers=headers) as response: - response.raise_for_status() - next = False - async for line in response.iter_lines(): - if line == b"event: line": - next = True - elif next and line.startswith(b"data: "): - yield json.loads(line[6:]) - next = False - diff --git a/g4f/Provider/unfinished/MikuChat.py b/g4f/Provider/unfinished/MikuChat.py deleted file mode 100644 index bf19631f..00000000 --- a/g4f/Provider/unfinished/MikuChat.py +++ /dev/null @@ -1,97 +0,0 @@ -from __future__ import annotations - -import random, json -from datetime import datetime -from ...requests import StreamSession - -from ...typing import AsyncGenerator -from ..base_provider import AsyncGeneratorProvider - - -class MikuChat(AsyncGeneratorProvider): - url = "https://ai.okmiku.com" - supports_gpt_35_turbo = True - - @classmethod - async def create_async_generator( - cls, - model: str, - messages: list[dict[str, str]], - **kwargs - ) -> AsyncGenerator: - if not model: - model = "gpt-3.5-turbo" - headers = { - "authority": "api.catgpt.cc", - "accept": "application/json", - "origin": cls.url, - "referer": f"{cls.url}/chat/", - 'x-app-version': 'undefined', - 'x-date': get_datetime(), - 'x-fingerprint': get_fingerprint(), - 'x-platform': 'web' - } - async with StreamSession(headers=headers, impersonate="chrome107") as session: - data = { - "model": model, - "top_p": 0.8, - "temperature": 0.5, - "presence_penalty": 1, - "frequency_penalty": 0, - "max_tokens": 2000, - "stream": True, - "messages": messages, - } - async with session.post("https://api.catgpt.cc/ai/v1/chat/completions", json=data) as response: - print(await response.text()) - response.raise_for_status() - async for line in response.iter_lines(): - if line.startswith(b"data: "): - line = json.loads(line[6:]) - chunk = line["choices"][0]["delta"].get("content") - if chunk: - yield chunk - -def k(e: str, t: int): - a = len(e) & 3 - s = len(e) - a - i = t - c = 3432918353 - o = 461845907 - n = 0 - r = 0 - while n < s: - r = (ord(e[n]) & 255) | ((ord(e[n + 1]) & 255) << 8) | ((ord(e[n + 2]) & 255) << 16) | ((ord(e[n + 3]) & 255) << 24) - n += 4 - r = (r & 65535) * c + (((r >> 16) * c & 65535) << 16) & 4294967295 - r = (r << 15) | (r >> 17) - r = (r & 65535) * o + (((r >> 16) * o & 65535) << 16) & 4294967295 - i ^= r - i = (i << 13) | (i >> 19) - l = (i & 65535) * 5 + (((i >> 16) * 5 & 65535) << 16) & 4294967295 - i = (l & 65535) + 27492 + (((l >> 16) + 58964 & 65535) << 16) - - if a == 3: - r ^= (ord(e[n + 2]) & 255) << 16 - elif a == 2: - r ^= (ord(e[n + 1]) & 255) << 8 - elif a == 1: - r ^= ord(e[n]) & 255 - r = (r & 65535) * c + (((r >> 16) * c & 65535) << 16) & 4294967295 - r = (r << 15) | (r >> 17) - r = (r & 65535) * o + (((r >> 16) * o & 65535) << 16) & 4294967295 - i ^= r - - i ^= len(e) - i ^= i >> 16 - i = (i & 65535) * 2246822507 + (((i >> 16) * 2246822507 & 65535) << 16) & 4294967295 - i ^= i >> 13 - i = (i & 65535) * 3266489909 + (((i >> 16) * 3266489909 & 65535) << 16) & 4294967295 - i ^= i >> 16 - return i & 0xFFFFFFFF - -def get_fingerprint() -> str: - return str(k(str(int(random.random() * 100000)), 256)) - -def get_datetime() -> str: - return datetime.now().strftime("%Y-%m-%d %H:%M:%S") \ No newline at end of file diff --git a/g4f/Provider/unfinished/__init__.py b/g4f/Provider/unfinished/__init__.py deleted file mode 100644 index eb5e8825..00000000 --- a/g4f/Provider/unfinished/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -from .MikuChat import MikuChat -from .Komo import Komo -from .ChatAiGpt import ChatAiGpt -from .AiChatting import AiChatting \ No newline at end of file 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 c985ddd3..f5980577 100644 --- a/g4f/models.py +++ b/g4f/models.py @@ -4,21 +4,20 @@ from dataclasses import dataclass from .Provider import IterListProvider, ProviderType from .Provider import ( - AiChatOnline, Airforce, Allyfy, Bing, Binjie, Bixin123, Blackbox, - ChatGot, - Chatgpt4Online, ChatGpt, Chatgpt4o, + Chatgpt4Online, + ChatGptEs, ChatgptFree, - CodeNews, DDG, DeepInfra, + DeepInfraChat, DeepInfraImage, Free2GPT, FreeChatgpt, @@ -31,6 +30,7 @@ from .Provider import ( HuggingFace, Koala, Liaobots, + LiteIcoding, MagickPen, MetaAI, Nexra, @@ -41,9 +41,7 @@ from .Provider import ( Reka, Replicate, ReplicateHome, - Snova, TeachAnything, - TwitterBio, Upstage, You, ) @@ -76,7 +74,6 @@ default = Model( FreeChatgpt, HuggingChat, Pizzagpt, - ChatgptFree, ReplicateHome, Upstage, Blackbox, @@ -84,6 +81,8 @@ default = Model( Binjie, Free2GPT, MagickPen, + DeepInfraChat, + LiteIcoding, ]) ) @@ -106,7 +105,7 @@ gpt_35_turbo = Model( name = 'gpt-3.5-turbo', base_provider = 'OpenAI', best_provider = IterListProvider([ - Allyfy, TwitterBio, Nexra, Bixin123, CodeNews, Airforce, + Allyfy, Nexra, Bixin123, Airforce, ]) ) @@ -115,7 +114,7 @@ gpt_4o = Model( name = 'gpt-4o', base_provider = 'OpenAI', best_provider = IterListProvider([ - Liaobots, Chatgpt4o, Airforce, + Liaobots, Airforce, Chatgpt4o, ChatGptEs, OpenaiChat ]) ) @@ -124,8 +123,8 @@ gpt_4o_mini = Model( name = 'gpt-4o-mini', base_provider = 'OpenAI', best_provider = IterListProvider([ - DDG, Liaobots, You, FreeNetfly, Pizzagpt, ChatgptFree, AiChatOnline, CodeNews, MagickPen, Airforce, - OpenaiChat, Koala, ChatGpt + DDG, ChatGptEs, You, FreeNetfly, Pizzagpt, LiteIcoding, MagickPen, Liaobots, Airforce, ChatgptFree, Koala, + OpenaiChat, ChatGpt ]) ) @@ -141,8 +140,26 @@ gpt_4 = Model( name = 'gpt-4', base_provider = 'OpenAI', best_provider = IterListProvider([ - Chatgpt4Online, Nexra, Binjie, Airforce, 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, + ]) +) + +# o1 +o1 = Model( + name = 'o1', + base_provider = 'OpenAI', + best_provider = IterListProvider([ + Liaobots + ]) +) + +o1_mini = Model( + name = 'o1-mini', + base_provider = 'OpenAI', + best_provider = IterListProvider([ + Liaobots ]) ) @@ -161,40 +178,55 @@ meta = Model( best_provider = MetaAI ) +# llama 2 llama_2_13b = Model( name = "llama-2-13b", - base_provider = "Meta", + base_provider = "Meta Llama", best_provider = IterListProvider([Airforce]) ) +# llama 3 llama_3_8b = Model( name = "llama-3-8b", - base_provider = "Meta", + base_provider = "Meta Llama", best_provider = IterListProvider([Airforce, DeepInfra, Replicate]) ) llama_3_70b = Model( name = "llama-3-70b", - base_provider = "Meta", + 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, Airforce, PerplexityLabs]) + base_provider = "Meta Llama", + best_provider = IterListProvider([Blackbox, DeepInfraChat, Airforce, PerplexityLabs]) ) llama_3_1_70b = Model( name = "llama-3.1-70b", - base_provider = "Meta", - best_provider = IterListProvider([DDG, HuggingChat, FreeGpt, Blackbox, TeachAnything, Free2GPT, Airforce, HuggingFace, PerplexityLabs]) + 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([Blackbox, Airforce]) + 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([llama_3_1_8b.best_provider, llama_3_1_70b.best_provider, llama_3_1_405b.best_provider,]) ) @@ -202,19 +234,19 @@ llama_3_1_405b = Model( mistral_7b = Model( name = "mistral-7b", base_provider = "Mistral", - best_provider = IterListProvider([HuggingChat, Airforce, HuggingFace, DeepInfra]) + best_provider = IterListProvider([HuggingChat, DeepInfraChat, Airforce, HuggingFace, DeepInfra]) ) mixtral_8x7b = Model( name = "mixtral-8x7b", base_provider = "Mistral", - best_provider = IterListProvider([HuggingChat, DDG, ReplicateHome, TwitterBio, Airforce, DeepInfra, HuggingFace]) + best_provider = IterListProvider([HuggingChat, DDG, ReplicateHome, DeepInfraChat, Airforce, DeepInfra, HuggingFace]) ) mixtral_8x22b = Model( name = "mixtral-8x22b", base_provider = "Mistral", - best_provider = IterListProvider([Airforce]) + best_provider = IterListProvider([DeepInfraChat, Airforce]) ) @@ -225,13 +257,6 @@ mixtral_8x7b_dpo = Model( best_provider = IterListProvider([HuggingChat, Airforce, HuggingFace]) ) -yi_34b = Model( - name = 'yi-34b', - base_provider = 'NousResearch', - best_provider = IterListProvider([Airforce]) -) - - ### Microsoft ### phi_3_mini_4k = Model( name = "phi-3-mini-4k", @@ -239,38 +264,37 @@ phi_3_mini_4k = Model( best_provider = IterListProvider([HuggingChat, HuggingFace]) ) +phi_3_medium_4k = Model( + name = "phi-3-medium-4k", + base_provider = "Microsoft", + best_provider = IterListProvider([DeepInfraChat]) +) -### Google ### + +### Google DeepMind ### # gemini gemini_pro = Model( name = 'gemini-pro', - base_provider = 'Google', - best_provider = IterListProvider([GeminiPro, ChatGot, Liaobots, Airforce]) + base_provider = 'Google DeepMind', + best_provider = IterListProvider([GeminiPro, LiteIcoding, Blackbox, Liaobots, Airforce]) ) gemini_flash = Model( name = 'gemini-flash', - base_provider = 'Google', + base_provider = 'Google DeepMind', best_provider = IterListProvider([Blackbox, Liaobots, Airforce]) ) gemini = Model( name = 'gemini', - base_provider = 'Google', + base_provider = 'Google DeepMind', best_provider = IterListProvider([ Gemini, gemini_flash.best_provider, gemini_pro.best_provider ]) ) - # gemma -gemma_2b = Model( - name = 'gemma-2b', - base_provider = 'Google', - best_provider = IterListProvider([ReplicateHome, Airforce]) -) - gemma_2b_9b = Model( name = 'gemma-2b-9b', base_provider = 'Google', @@ -280,9 +304,19 @@ gemma_2b_9b = Model( gemma_2b_27b = Model( name = 'gemma-2b-27b', base_provider = 'Google', - best_provider = IterListProvider([Airforce]) + best_provider = IterListProvider([DeepInfraChat, Airforce]) ) +gemma_2b = Model( + name = 'gemma-2b', + base_provider = 'Google', + best_provider = IterListProvider([ + ReplicateHome, Airforce, + gemma_2b_9b.best_provider, gemma_2b_27b.best_provider, + ]) +) + + ### Anthropic ### claude_2 = Model( name = 'claude-2', @@ -302,6 +336,7 @@ claude_2_1 = Model( best_provider = IterListProvider([Liaobots]) ) +# claude 3 claude_3_opus = Model( name = 'claude-3-opus', base_provider = 'Anthropic', @@ -314,19 +349,38 @@ claude_3_sonnet = Model( best_provider = IterListProvider([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', @@ -335,11 +389,11 @@ reka_core = Model( ) -### Blackbox ### +### Blackbox AI ### blackbox = Model( name = 'blackbox', - base_provider = 'Blackbox', - best_provider = Blackbox + base_provider = 'Blackbox AI', + best_provider = IterListProvider([Blackbox]) ) @@ -366,6 +420,7 @@ sparkdesk_v1_1 = Model( best_provider = IterListProvider([FreeChatgpt, Airforce]) ) + ### Qwen ### qwen_1_5_14b = Model( name = 'qwen-1.5-14b', @@ -388,7 +443,7 @@ qwen_1_5_110b = Model( qwen_2_72b = Model( name = 'qwen-2-72b', base_provider = 'Qwen', - best_provider = IterListProvider([Airforce]) + best_provider = IterListProvider([DeepInfraChat, Airforce]) ) qwen_turbo = Model( @@ -397,6 +452,14 @@ qwen_turbo = Model( best_provider = IterListProvider([Bixin123]) ) +qwen = Model( + name = 'qwen', + base_provider = 'Qwen', + best_provider = IterListProvider([ + 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 + ]) +) + ### Zhipu AI ### glm_3_6b = Model( @@ -415,11 +478,11 @@ glm_4 = Model( name = 'glm-4', base_provider = 'Zhipu AI', best_provider = IterListProvider([ - CodeNews, glm_3_6b.best_provider, glm_4_9b.best_provider ]) ) + ### 01-ai ### yi_1_5_9b = Model( name = 'yi-1.5-9b', @@ -427,6 +490,13 @@ yi_1_5_9b = Model( best_provider = IterListProvider([FreeChatgpt]) ) +yi_34b = Model( + name = 'yi-34b', + base_provider = '01-ai', + best_provider = IterListProvider([Airforce]) +) + + ### Upstage ### solar_1_mini = Model( name = 'solar-1-mini', @@ -440,47 +510,38 @@ solar_10_7b = Model( 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 -) - -### Trong-Hieu Nguyen-Mau ### -v1olet_merged_7b = Model( - name = 'v1olet-merged-7b', - base_provider = 'Trong-Hieu Nguyen-Mau', - best_provider = Snova -) - -### Macadeliccc ### -westlake_7b_v2 = Model( - name = 'westlake-7b-v2', - base_provider = 'Macadeliccc', - best_provider = Snova -) - ### DeepSeek ### deepseek = Model( name = 'deepseek', base_provider = 'DeepSeek', - best_provider = IterListProvider([CodeNews, Airforce]) + best_provider = IterListProvider([Airforce]) ) ### WizardLM ### +wizardlm_2_7b = Model( + name = 'wizardlm-2-7b', + base_provider = 'WizardLM', + best_provider = IterListProvider([DeepInfraChat]) +) + wizardlm_2_8x22b = Model( name = 'wizardlm-2-8x22b', base_provider = 'WizardLM', - best_provider = Airforce + best_provider = IterListProvider([DeepInfraChat, Airforce]) ) ### Together ### @@ -490,6 +551,7 @@ sh_n_7b = Model( best_provider = Airforce ) + ### Yorickvp ### llava_13b = Model( name = 'llava-13b', @@ -497,6 +559,62 @@ llava_13b = Model( 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 +) + + + ############# ### Image ### ############# @@ -516,10 +634,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]) ) @@ -528,7 +647,7 @@ playground_v2_5 = Model( flux = Model( name = 'flux', base_provider = 'Flux AI', - best_provider = IterListProvider([Airforce]) + best_provider = IterListProvider([Airforce, Blackbox]) ) @@ -567,6 +686,13 @@ flux_pixel = Model( ) +flux_4o = Model( + name = 'flux-4o', + base_provider = 'Flux AI', + best_provider = IterListProvider([Airforce]) + +) + flux_schnell = Model( name = 'flux-schnell', base_provider = 'Flux AI', @@ -574,18 +700,28 @@ flux_schnell = Model( ) + ### ### -dalle = Model( - name = 'dalle', +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_2 = Model( - name = 'dalle-2', +dalle = Model( + name = 'dalle', base_provider = '', - best_provider = IterListProvider([Nexra]) + best_provider = IterListProvider([ + Nexra, + dalle_2.best_provider, dalle_3.best_provider, + ]) ) @@ -596,6 +732,7 @@ dalle_mini = Model( ) +### ### emi = Model( name = 'emi', base_provider = '', @@ -631,10 +768,14 @@ 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, + +# o1 +'o1': o1, +'o1-mini': o1_mini, ### Meta ### @@ -644,10 +785,12 @@ class ModelUtils: '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, @@ -667,6 +810,7 @@ class ModelUtils: ### Microsoft ### 'phi-3-mini-4k': phi_3_mini_4k, +'phi_3_medium-4k': phi_3_medium_4k, ### Google ### @@ -685,18 +829,23 @@ class ModelUtils: '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-haiku': claude_3_haiku, -'claude-3-5-sonnet': claude_3_5_sonnet, + +# 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, @@ -717,6 +866,7 @@ 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, @@ -737,24 +887,12 @@ class ModelUtils: ### Upstage ### 'solar-1-mini': solar_1_mini, 'solar-10-7b': solar_10_7b, +'solar-pro': solar_pro, -### Pi ### +### Inflection ### 'pi': pi, - -### SambaNova ### -'samba-coe-v0.1': samba_coe_v0_1, - - -### Trong-Hieu Nguyen-Mau ### -'v1olet-merged-7b': v1olet_merged_7b, - - -### Macadeliccc ### -'westlake-7b-v2': westlake_7b_v2, - - ### DeepSeek ### 'deepseek': deepseek, @@ -765,6 +903,36 @@ class ModelUtils: ### Yorickvp ### 'llava-13b': llava_13b, + + +### 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, + + +### 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, @@ -788,12 +956,14 @@ class ModelUtils: '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, -- cgit v1.2.3 From 0c18ed5ce23a8bce90d80b9d1200391b34151871 Mon Sep 17 00:00:00 2001 From: kqlio67 Date: Tue, 24 Sep 2024 15:37:14 +0300 Subject: Returned provider 'g4f/Provider/ChatGot.py' updated documentation 'docs/providers-and-models.md' --- g4f/Provider/ChatGot.py | 75 ++++++++++++++++++++++++++++++++++++++++++++++++ g4f/Provider/__init__.py | 1 + 2 files changed, 76 insertions(+) create mode 100644 g4f/Provider/ChatGot.py (limited to 'g4f') diff --git a/g4f/Provider/ChatGot.py b/g4f/Provider/ChatGot.py new file mode 100644 index 00000000..55e8d0b6 --- /dev/null +++ b/g4f/Provider/ChatGot.py @@ -0,0 +1,75 @@ +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 ChatGot(AsyncGeneratorProvider, ProviderModelMixin): + url = "https://www.chatgot.one/" + working = 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/__init__.py b/g4f/Provider/__init__.py index 30148f27..087c9c8a 100644 --- a/g4f/Provider/__init__.py +++ b/g4f/Provider/__init__.py @@ -19,6 +19,7 @@ from .BingCreateImages import BingCreateImages from .Binjie import Binjie from .Bixin123 import Bixin123 from .Blackbox import Blackbox +from .ChatGot import ChatGot from .ChatGpt import ChatGpt from .Chatgpt4Online import Chatgpt4Online from .Chatgpt4o import Chatgpt4o -- cgit v1.2.3 From a6099ba48beeba7911a61dd4c2af2ba324ab23f0 Mon Sep 17 00:00:00 2001 From: kqlio67 Date: Wed, 25 Sep 2024 08:01:39 +0300 Subject: feat(g4f/Provider/HuggingChat.): add Qwen2.5-72B model and alias --- g4f/Provider/Blackbox.py | 3 +-- g4f/Provider/HuggingChat.py | 2 ++ g4f/models.py | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) (limited to 'g4f') diff --git a/g4f/Provider/Blackbox.py b/g4f/Provider/Blackbox.py index 40696c82..3e183076 100644 --- a/g4f/Provider/Blackbox.py +++ b/g4f/Provider/Blackbox.py @@ -154,7 +154,6 @@ class Blackbox(AsyncGeneratorProvider, ProviderModelMixin): async for chunk in response.content.iter_any(): if chunk: decoded_chunk = chunk.decode() - # Видаляємо префікс $@$v=v1.10-rv1$@$ та інші подібні decoded_chunk = re.sub(r'\$@\$v=[^$]+\$@\$', '', decoded_chunk) - if decoded_chunk.strip(): # Перевіряємо, чи залишився якийсь текст після видалення префікса + if decoded_chunk.strip(): yield decoded_chunk diff --git a/g4f/Provider/HuggingChat.py b/g4f/Provider/HuggingChat.py index 06216ade..01490e2f 100644 --- a/g4f/Provider/HuggingChat.py +++ b/g4f/Provider/HuggingChat.py @@ -16,6 +16,7 @@ class HuggingChat(AbstractProvider, ProviderModelMixin): models = [ 'meta-llama/Meta-Llama-3.1-70B-Instruct', 'CohereForAI/c4ai-command-r-plus-08-2024', + 'Qwen/Qwen2.5-72B-Instruct', 'mistralai/Mixtral-8x7B-Instruct-v0.1', 'NousResearch/Nous-Hermes-2-Mixtral-8x7B-DPO', 'mistralai/Mistral-7B-Instruct-v0.3', @@ -25,6 +26,7 @@ class HuggingChat(AbstractProvider, ProviderModelMixin): model_aliases = { "llama-3.1-70b": "meta-llama/Meta-Llama-3.1-70B-Instruct", "command-r-plus": "CohereForAI/c4ai-command-r-plus-08-2024", + "qwen-2-72b": "Qwen/Qwen2.5-72B-Instruct", "mixtral-8x7b": "mistralai/Mixtral-8x7B-Instruct-v0.1", "mixtral-8x7b-dpo": "NousResearch/Nous-Hermes-2-Mixtral-8x7B-DPO", "mistral-7b": "mistralai/Mistral-7B-Instruct-v0.3", diff --git a/g4f/models.py b/g4f/models.py index f5980577..2f4405a3 100644 --- a/g4f/models.py +++ b/g4f/models.py @@ -443,7 +443,7 @@ qwen_1_5_110b = Model( qwen_2_72b = Model( name = 'qwen-2-72b', base_provider = 'Qwen', - best_provider = IterListProvider([DeepInfraChat, Airforce]) + best_provider = IterListProvider([DeepInfraChat, HuggingChat, Airforce, HuggingFace]) ) qwen_turbo = Model( -- cgit v1.2.3 From ec4e25073b5357a1213bfe00a93a21b5b6652bea Mon Sep 17 00:00:00 2001 From: kqlio67 Date: Wed, 25 Sep 2024 11:44:23 +0300 Subject: The restored directory 'g4f/Provider/deprecated' --- g4f/Provider/__init__.py | 1 + g4f/Provider/deprecated/Acytoo.py | 51 ++++ g4f/Provider/deprecated/AiAsk.py | 46 ++++ g4f/Provider/deprecated/AiService.py | 39 +++ g4f/Provider/deprecated/Aibn.py | 46 ++++ g4f/Provider/deprecated/Aichat.py | 64 +++++ g4f/Provider/deprecated/Ails.py | 90 +++++++ g4f/Provider/deprecated/Aivvm.py | 73 ++++++ g4f/Provider/deprecated/Berlin.py | 78 ++++++ g4f/Provider/deprecated/ChatAnywhere.py | 54 +++++ g4f/Provider/deprecated/ChatgptDuo.py | 47 ++++ g4f/Provider/deprecated/CodeLinkAva.py | 52 ++++ g4f/Provider/deprecated/Cromicle.py | 50 ++++ g4f/Provider/deprecated/DfeHub.py | 62 +++++ g4f/Provider/deprecated/EasyChat.py | 89 +++++++ g4f/Provider/deprecated/Equing.py | 71 ++++++ g4f/Provider/deprecated/FakeGpt.py | 91 +++++++ g4f/Provider/deprecated/FastGpt.py | 76 ++++++ g4f/Provider/deprecated/Forefront.py | 40 ++++ g4f/Provider/deprecated/GPTalk.py | 87 +++++++ g4f/Provider/deprecated/GeekGpt.py | 73 ++++++ g4f/Provider/deprecated/GetGpt.py | 77 ++++++ g4f/Provider/deprecated/H2o.py | 89 +++++++ g4f/Provider/deprecated/Hashnode.py | 80 +++++++ g4f/Provider/deprecated/Lockchat.py | 54 +++++ g4f/Provider/deprecated/Myshell.py | 165 +++++++++++++ g4f/Provider/deprecated/NoowAi.py | 66 ++++++ g4f/Provider/deprecated/Opchatgpts.py | 59 +++++ g4f/Provider/deprecated/OpenAssistant.py | 88 +++++++ g4f/Provider/deprecated/Phind.py | 140 +++++++++++ g4f/Provider/deprecated/V50.py | 61 +++++ g4f/Provider/deprecated/Vercel.py | 392 +++++++++++++++++++++++++++++++ g4f/Provider/deprecated/Vitalentum.py | 55 +++++ g4f/Provider/deprecated/VoiGpt.py | 91 +++++++ g4f/Provider/deprecated/Wewordle.py | 65 +++++ g4f/Provider/deprecated/Wuguokai.py | 57 +++++ g4f/Provider/deprecated/Ylokh.py | 58 +++++ g4f/Provider/deprecated/Yqcloud.py | 61 +++++ g4f/Provider/deprecated/__init__.py | 35 +++ 39 files changed, 2973 insertions(+) create mode 100644 g4f/Provider/deprecated/Acytoo.py create mode 100644 g4f/Provider/deprecated/AiAsk.py create mode 100644 g4f/Provider/deprecated/AiService.py create mode 100644 g4f/Provider/deprecated/Aibn.py create mode 100644 g4f/Provider/deprecated/Aichat.py create mode 100644 g4f/Provider/deprecated/Ails.py create mode 100644 g4f/Provider/deprecated/Aivvm.py create mode 100644 g4f/Provider/deprecated/Berlin.py create mode 100644 g4f/Provider/deprecated/ChatAnywhere.py create mode 100644 g4f/Provider/deprecated/ChatgptDuo.py create mode 100644 g4f/Provider/deprecated/CodeLinkAva.py create mode 100644 g4f/Provider/deprecated/Cromicle.py create mode 100644 g4f/Provider/deprecated/DfeHub.py create mode 100644 g4f/Provider/deprecated/EasyChat.py create mode 100644 g4f/Provider/deprecated/Equing.py create mode 100644 g4f/Provider/deprecated/FakeGpt.py create mode 100644 g4f/Provider/deprecated/FastGpt.py create mode 100644 g4f/Provider/deprecated/Forefront.py create mode 100644 g4f/Provider/deprecated/GPTalk.py create mode 100644 g4f/Provider/deprecated/GeekGpt.py create mode 100644 g4f/Provider/deprecated/GetGpt.py create mode 100644 g4f/Provider/deprecated/H2o.py create mode 100644 g4f/Provider/deprecated/Hashnode.py create mode 100644 g4f/Provider/deprecated/Lockchat.py create mode 100644 g4f/Provider/deprecated/Myshell.py create mode 100644 g4f/Provider/deprecated/NoowAi.py create mode 100644 g4f/Provider/deprecated/Opchatgpts.py create mode 100644 g4f/Provider/deprecated/OpenAssistant.py create mode 100644 g4f/Provider/deprecated/Phind.py create mode 100644 g4f/Provider/deprecated/V50.py create mode 100644 g4f/Provider/deprecated/Vercel.py create mode 100644 g4f/Provider/deprecated/Vitalentum.py create mode 100644 g4f/Provider/deprecated/VoiGpt.py create mode 100644 g4f/Provider/deprecated/Wewordle.py create mode 100644 g4f/Provider/deprecated/Wuguokai.py create mode 100644 g4f/Provider/deprecated/Ylokh.py create mode 100644 g4f/Provider/deprecated/Yqcloud.py create mode 100644 g4f/Provider/deprecated/__init__.py (limited to 'g4f') diff --git a/g4f/Provider/__init__.py b/g4f/Provider/__init__.py index 087c9c8a..515f5912 100644 --- a/g4f/Provider/__init__.py +++ b/g4f/Provider/__init__.py @@ -5,6 +5,7 @@ from ..providers.retry_provider import RetryProvider, IterListProvider from ..providers.base_provider import AsyncProvider, AsyncGeneratorProvider from ..providers.create_images import CreateImagesProvider +from .deprecated import * from .selenium import * from .needs_auth import * diff --git a/g4f/Provider/deprecated/Acytoo.py b/g4f/Provider/deprecated/Acytoo.py new file mode 100644 index 00000000..f75821ce --- /dev/null +++ b/g4f/Provider/deprecated/Acytoo.py @@ -0,0 +1,51 @@ +from __future__ import annotations + +from aiohttp import ClientSession + +from ...typing import AsyncResult, Messages +from ..base_provider import AsyncGeneratorProvider + + +class Acytoo(AsyncGeneratorProvider): + url = 'https://chat.acytoo.com' + working = False + supports_message_history = True + supports_gpt_35_turbo = True + + @classmethod + async def create_async_generator( + cls, + model: str, + messages: Messages, + proxy: str = None, + **kwargs + ) -> AsyncResult: + async with ClientSession( + headers=_create_header() + ) as session: + async with session.post( + f'{cls.url}/api/completions', + proxy=proxy, + json=_create_payload(messages, **kwargs) + ) as response: + response.raise_for_status() + async for stream in response.content.iter_any(): + if stream: + yield stream.decode() + + +def _create_header(): + return { + 'accept': '*/*', + 'content-type': 'application/json', + } + + +def _create_payload(messages: Messages, temperature: float = 0.5, **kwargs): + return { + 'key' : '', + 'model' : 'gpt-3.5-turbo', + 'messages' : messages, + 'temperature' : temperature, + 'password' : '' + } \ No newline at end of file diff --git a/g4f/Provider/deprecated/AiAsk.py b/g4f/Provider/deprecated/AiAsk.py new file mode 100644 index 00000000..6ea5f3e0 --- /dev/null +++ b/g4f/Provider/deprecated/AiAsk.py @@ -0,0 +1,46 @@ +from __future__ import annotations + +from aiohttp import ClientSession +from ...typing import AsyncResult, Messages +from ..base_provider import AsyncGeneratorProvider + +class AiAsk(AsyncGeneratorProvider): + url = "https://e.aiask.me" + supports_message_history = True + supports_gpt_35_turbo = True + working = False + + @classmethod + async def create_async_generator( + cls, + model: str, + messages: Messages, + proxy: str = None, + **kwargs + ) -> AsyncResult: + headers = { + "accept": "application/json, text/plain, */*", + "origin": cls.url, + "referer": f"{cls.url}/chat", + } + async with ClientSession(headers=headers) as session: + data = { + "continuous": True, + "id": "fRMSQtuHl91A4De9cCvKD", + "list": messages, + "models": "0", + "prompt": "", + "temperature": kwargs.get("temperature", 0.5), + "title": "", + } + buffer = "" + rate_limit = "您的免费额度不够使用这个模型啦,请点击右上角登录继续使用!" + async with session.post(f"{cls.url}/v1/chat/gpt/", json=data, proxy=proxy) as response: + response.raise_for_status() + async for chunk in response.content.iter_any(): + buffer += chunk.decode() + if not rate_limit.startswith(buffer): + yield buffer + buffer = "" + elif buffer == rate_limit: + raise RuntimeError("Rate limit reached") \ No newline at end of file diff --git a/g4f/Provider/deprecated/AiService.py b/g4f/Provider/deprecated/AiService.py new file mode 100644 index 00000000..acd7f5ea --- /dev/null +++ b/g4f/Provider/deprecated/AiService.py @@ -0,0 +1,39 @@ +from __future__ import annotations + +import requests + +from ...typing import Any, CreateResult, Messages +from ..base_provider import AbstractProvider + + +class AiService(AbstractProvider): + url = "https://aiservice.vercel.app/" + working = False + supports_gpt_35_turbo = True + + @staticmethod + def create_completion( + model: str, + messages: Messages, + stream: bool, + **kwargs: Any, + ) -> CreateResult: + base = ( + "\n".join( + f"{message['role']}: {message['content']}" for message in messages + ) + + "\nassistant: " + ) + headers = { + "accept": "*/*", + "content-type": "text/plain;charset=UTF-8", + "sec-fetch-dest": "empty", + "sec-fetch-mode": "cors", + "sec-fetch-site": "same-origin", + "Referer": "https://aiservice.vercel.app/chat", + } + data = {"input": base} + url = "https://aiservice.vercel.app/api/chat/answer" + response = requests.post(url, headers=headers, json=data) + response.raise_for_status() + yield response.json()["data"] diff --git a/g4f/Provider/deprecated/Aibn.py b/g4f/Provider/deprecated/Aibn.py new file mode 100644 index 00000000..0bbfb436 --- /dev/null +++ b/g4f/Provider/deprecated/Aibn.py @@ -0,0 +1,46 @@ +from __future__ import annotations + +import time +import hashlib + +from ...typing import AsyncResult, Messages +from ...requests import StreamSession +from ..base_provider import AsyncGeneratorProvider + + +class Aibn(AsyncGeneratorProvider): + url = "https://aibn.cc" + working = False + supports_message_history = True + supports_gpt_35_turbo = True + + @classmethod + async def create_async_generator( + cls, + model: str, + messages: Messages, + proxy: str = None, + timeout: int = 120, + **kwargs + ) -> AsyncResult: + async with StreamSession( + impersonate="chrome107", + proxies={"https": proxy}, + timeout=timeout + ) as session: + timestamp = int(time.time()) + data = { + "messages": messages, + "pass": None, + "sign": generate_signature(timestamp, messages[-1]["content"]), + "time": timestamp + } + async with session.post(f"{cls.url}/api/generate", json=data) as response: + response.raise_for_status() + async for chunk in response.iter_content(): + yield chunk.decode() + + +def generate_signature(timestamp: int, message: str, secret: str = "undefined"): + data = f"{timestamp}:{message}:{secret}" + return hashlib.sha256(data.encode()).hexdigest() \ No newline at end of file diff --git a/g4f/Provider/deprecated/Aichat.py b/g4f/Provider/deprecated/Aichat.py new file mode 100644 index 00000000..68c9c546 --- /dev/null +++ b/g4f/Provider/deprecated/Aichat.py @@ -0,0 +1,64 @@ +from __future__ import annotations + +from ...typing import Messages +from ..base_provider import AsyncProvider, format_prompt +from ..helper import get_cookies +from ...requests import StreamSession + +class Aichat(AsyncProvider): + url = "https://chat-gpt.org/chat" + working = False + supports_gpt_35_turbo = True + + @staticmethod + async def create_async( + model: str, + messages: Messages, + proxy: str = None, **kwargs) -> str: + + cookies = get_cookies('chat-gpt.org') if not kwargs.get('cookies') else kwargs.get('cookies') + if not cookies: + raise RuntimeError( + "g4f.provider.Aichat requires cookies, [refresh https://chat-gpt.org on chrome]" + ) + + headers = { + 'authority': 'chat-gpt.org', + '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', + 'content-type': 'application/json', + 'origin': 'https://chat-gpt.org', + 'referer': 'https://chat-gpt.org/chat', + 'sec-ch-ua': '"Chromium";v="118", "Google Chrome";v="118", "Not=A?Brand";v="99"', + '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/118.0.0.0 Safari/537.36', + } + + async with StreamSession(headers=headers, + cookies=cookies, + timeout=6, + proxies={"https": proxy} if proxy else None, + impersonate="chrome110", verify=False) as session: + + json_data = { + "message": format_prompt(messages), + "temperature": kwargs.get('temperature', 0.5), + "presence_penalty": 0, + "top_p": kwargs.get('top_p', 1), + "frequency_penalty": 0, + } + + async with session.post("https://chat-gpt.org/api/text", + json=json_data) as response: + + response.raise_for_status() + result = await response.json() + + if not result['response']: + raise Exception(f"Error Response: {result}") + + return result["message"] diff --git a/g4f/Provider/deprecated/Ails.py b/g4f/Provider/deprecated/Ails.py new file mode 100644 index 00000000..e87ceb32 --- /dev/null +++ b/g4f/Provider/deprecated/Ails.py @@ -0,0 +1,90 @@ +from __future__ import annotations + +import hashlib +import time +import uuid +import json +from datetime import datetime +from aiohttp import ClientSession + +from ...typing import SHA256, AsyncResult, Messages +from ..base_provider import AsyncGeneratorProvider + + +class Ails(AsyncGeneratorProvider): + url = "https://ai.ls" + working = False + supports_message_history = True + supports_gpt_35_turbo = True + + @staticmethod + async def create_async_generator( + model: str, + messages: Messages, + stream: bool, + proxy: str = None, + **kwargs + ) -> AsyncResult: + headers = { + "authority": "api.caipacity.com", + "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", + "authorization": "Bearer free", + "client-id": str(uuid.uuid4()), + "client-v": "0.1.278", + "content-type": "application/json", + "origin": "https://ai.ls", + "referer": "https://ai.ls/", + "sec-ch-ua": '"Not.A/Brand";v="8", "Chromium";v="114", "Google Chrome";v="114"', + "sec-ch-ua-mobile": "?0", + "sec-ch-ua-platform": '"Windows"', + "sec-fetch-dest": "empty", + "sec-fetch-mode": "cors", + "sec-fetch-site": "cross-site", + "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36", + "from-url": "https://ai.ls/?chat=1" + } + async with ClientSession( + headers=headers + ) as session: + timestamp = _format_timestamp(int(time.time() * 1000)) + json_data = { + "model": "gpt-3.5-turbo", + "temperature": kwargs.get("temperature", 0.6), + "stream": True, + "messages": messages, + "d": datetime.now().strftime("%Y-%m-%d"), + "t": timestamp, + "s": _hash({"t": timestamp, "m": messages[-1]["content"]}), + } + async with session.post( + "https://api.caipacity.com/v1/chat/completions", + proxy=proxy, + json=json_data + ) as response: + response.raise_for_status() + start = "data: " + async for line in response.content: + line = line.decode('utf-8') + if line.startswith(start) and line != "data: [DONE]": + line = line[len(start):-1] + line = json.loads(line) + token = line["choices"][0]["delta"].get("content") + + if token: + if "ai.ls" in token or "ai.ci" in token: + raise Exception(f"Response Error: {token}") + yield token + + +def _hash(json_data: dict[str, str]) -> SHA256: + base_string: str = f'{json_data["t"]}:{json_data["m"]}:WI,2rU#_r:r~aF4aJ36[.Z(/8Rv93Rf:{len(json_data["m"])}' + + return SHA256(hashlib.sha256(base_string.encode()).hexdigest()) + + +def _format_timestamp(timestamp: int) -> str: + e = timestamp + n = e % 10 + r = n + 1 if n % 2 == 0 else n + return str(e - n + r) \ No newline at end of file diff --git a/g4f/Provider/deprecated/Aivvm.py b/g4f/Provider/deprecated/Aivvm.py new file mode 100644 index 00000000..c973adf8 --- /dev/null +++ b/g4f/Provider/deprecated/Aivvm.py @@ -0,0 +1,73 @@ +from __future__ import annotations + +import requests +import json + +from ..base_provider import AbstractProvider +from ...typing import CreateResult, Messages + +# to recreate this easily, send a post request to https://chat.aivvm.com/api/models +models = { + 'gpt-3.5-turbo': {'id': 'gpt-3.5-turbo', 'name': 'GPT-3.5'}, + 'gpt-3.5-turbo-0613': {'id': 'gpt-3.5-turbo-0613', 'name': 'GPT-3.5-0613'}, + 'gpt-3.5-turbo-16k': {'id': 'gpt-3.5-turbo-16k', 'name': 'GPT-3.5-16K'}, + 'gpt-3.5-turbo-16k-0613': {'id': 'gpt-3.5-turbo-16k-0613', 'name': 'GPT-3.5-16K-0613'}, + 'gpt-4': {'id': 'gpt-4', 'name': 'GPT-4'}, + 'gpt-4-0613': {'id': 'gpt-4-0613', 'name': 'GPT-4-0613'}, + 'gpt-4-32k': {'id': 'gpt-4-32k', 'name': 'GPT-4-32K'}, + 'gpt-4-32k-0613': {'id': 'gpt-4-32k-0613', 'name': 'GPT-4-32K-0613'}, +} + +class Aivvm(AbstractProvider): + url = 'https://chat.aivvm.com' + supports_stream = True + working = False + supports_gpt_35_turbo = True + supports_gpt_4 = True + + @classmethod + def create_completion(cls, + model: str, + messages: Messages, + stream: bool, + **kwargs + ) -> CreateResult: + if not model: + model = "gpt-3.5-turbo" + elif model not in models: + raise ValueError(f"Model is not supported: {model}") + + json_data = { + "model" : models[model], + "messages" : messages, + "key" : "", + "prompt" : kwargs.get("system_message", "You are ChatGPT, a large language model trained by OpenAI. Follow the user's instructions carefully. Respond using markdown."), + "temperature" : kwargs.get("temperature", 0.7) + } + + data = json.dumps(json_data) + + headers = { + "accept" : "text/event-stream", + "accept-language" : "en-US,en;q=0.9", + "content-type" : "application/json", + "content-length" : str(len(data)), + "sec-ch-ua" : "\"Chrome\";v=\"117\", \"Not;A=Brand\";v=\"8\", \"Chromium\";v=\"117\"", + "sec-ch-ua-mobile" : "?0", + "sec-ch-ua-platform": "\"Windows\"", + "sec-fetch-dest" : "empty", + "sec-fetch-mode" : "cors", + "sec-fetch-site" : "same-origin", + "sec-gpc" : "1", + "referrer" : "https://chat.aivvm.com/", + "user-agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36" + } + + response = requests.post("https://chat.aivvm.com/api/chat", headers=headers, data=data, stream=True) + response.raise_for_status() + + for chunk in response.iter_content(chunk_size=4096): + try: + yield chunk.decode("utf-8") + except UnicodeDecodeError: + yield chunk.decode("unicode-escape") \ No newline at end of file diff --git a/g4f/Provider/deprecated/Berlin.py b/g4f/Provider/deprecated/Berlin.py new file mode 100644 index 00000000..5e81705a --- /dev/null +++ b/g4f/Provider/deprecated/Berlin.py @@ -0,0 +1,78 @@ +from __future__ import annotations + +import secrets +import uuid +import json +from aiohttp import ClientSession + +from ...typing import AsyncResult, Messages +from ..base_provider import AsyncGeneratorProvider +from ..helper import format_prompt + + +class Berlin(AsyncGeneratorProvider): + url = "https://ai.berlin4h.top" + working = False + supports_gpt_35_turbo = True + _token = None + + @classmethod + async def create_async_generator( + cls, + model: str, + messages: Messages, + proxy: str = None, + **kwargs + ) -> AsyncResult: + if not model: + model = "gpt-3.5-turbo" + headers = { + "User-Agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/119.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": "application/json", + "Origin": cls.url, + "Alt-Used": "ai.berlin4h.top", + "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: + if not cls._token: + data = { + "account": '免费使用GPT3.5模型@163.com', + "password": '659e945c2d004686bad1a75b708c962f' + } + async with session.post(f"{cls.url}/api/login", json=data, proxy=proxy) as response: + response.raise_for_status() + cls._token = (await response.json())["data"]["token"] + headers = { + "token": cls._token + } + prompt = format_prompt(messages) + data = { + "prompt": prompt, + "parentMessageId": str(uuid.uuid4()), + "options": { + "model": model, + "temperature": 0, + "presence_penalty": 0, + "frequency_penalty": 0, + "max_tokens": 1888, + **kwargs + }, + } + async with session.post(f"{cls.url}/api/chat/completions", json=data, proxy=proxy, headers=headers) as response: + response.raise_for_status() + async for chunk in response.content: + if chunk.strip(): + try: + yield json.loads(chunk)["content"] + except: + raise RuntimeError(f"Response: {chunk.decode()}") diff --git a/g4f/Provider/deprecated/ChatAnywhere.py b/g4f/Provider/deprecated/ChatAnywhere.py new file mode 100644 index 00000000..d035eaf0 --- /dev/null +++ b/g4f/Provider/deprecated/ChatAnywhere.py @@ -0,0 +1,54 @@ +from __future__ import annotations + +from aiohttp import ClientSession, ClientTimeout + +from ...typing import AsyncResult, Messages +from ..base_provider import AsyncGeneratorProvider + + +class ChatAnywhere(AsyncGeneratorProvider): + url = "https://chatanywhere.cn" + supports_gpt_35_turbo = True + supports_message_history = True + working = False + + @classmethod + async def create_async_generator( + cls, + model: str, + messages: Messages, + proxy: str = None, + timeout: int = 120, + temperature: float = 0.5, + **kwargs + ) -> AsyncResult: + headers = { + "User-Agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/119.0", + "Accept": "application/json, text/plain, */*", + "Accept-Language": "de,en-US;q=0.7,en;q=0.3", + "Accept-Encoding": "gzip, deflate, br", + "Content-Type": "application/json", + "Referer": f"{cls.url}/", + "Origin": cls.url, + "Sec-Fetch-Dest": "empty", + "Sec-Fetch-Mode": "cors", + "Sec-Fetch-Site": "same-origin", + "Authorization": "", + "Connection": "keep-alive", + "TE": "trailers" + } + async with ClientSession(headers=headers, timeout=ClientTimeout(timeout)) as session: + data = { + "list": messages, + "id": "s1_qYuOLXjI3rEpc7WHfQ", + "title": messages[-1]["content"], + "prompt": "", + "temperature": temperature, + "models": "61490748", + "continuous": True + } + async with session.post(f"{cls.url}/v1/chat/gpt/", json=data, proxy=proxy) as response: + response.raise_for_status() + async for chunk in response.content.iter_any(): + if chunk: + yield chunk.decode() \ No newline at end of file diff --git a/g4f/Provider/deprecated/ChatgptDuo.py b/g4f/Provider/deprecated/ChatgptDuo.py new file mode 100644 index 00000000..bd9e195d --- /dev/null +++ b/g4f/Provider/deprecated/ChatgptDuo.py @@ -0,0 +1,47 @@ +from __future__ import annotations + +from ...typing import Messages +from ...requests import StreamSession +from ..base_provider import AsyncProvider, format_prompt + + +class ChatgptDuo(AsyncProvider): + url = "https://chatgptduo.com" + supports_gpt_35_turbo = True + working = False + + @classmethod + async def create_async( + cls, + model: str, + messages: Messages, + proxy: str = None, + timeout: int = 120, + **kwargs + ) -> str: + async with StreamSession( + impersonate="chrome107", + proxies={"https": proxy}, + timeout=timeout + ) as session: + prompt = format_prompt(messages), + data = { + "prompt": prompt, + "search": prompt, + "purpose": "ask", + } + response = await session.post(f"{cls.url}/", data=data) + response.raise_for_status() + data = response.json() + + cls._sources = [{ + "title": source["title"], + "url": source["link"], + "snippet": source["snippet"] + } for source in data["results"]] + + return data["answer"] + + @classmethod + def get_sources(cls): + return cls._sources \ No newline at end of file diff --git a/g4f/Provider/deprecated/CodeLinkAva.py b/g4f/Provider/deprecated/CodeLinkAva.py new file mode 100644 index 00000000..22f4468a --- /dev/null +++ b/g4f/Provider/deprecated/CodeLinkAva.py @@ -0,0 +1,52 @@ +from __future__ import annotations + +from aiohttp import ClientSession +import json + +from ...typing import AsyncGenerator +from ..base_provider import AsyncGeneratorProvider + + +class CodeLinkAva(AsyncGeneratorProvider): + url = "https://ava-ai-ef611.web.app" + supports_gpt_35_turbo = True + working = False + + @classmethod + async def create_async_generator( + cls, + model: str, + messages: list[dict[str, str]], + **kwargs + ) -> AsyncGenerator: + headers = { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36", + "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", + "Origin": cls.url, + "Referer": f"{cls.url}/", + "Sec-Fetch-Dest": "empty", + "Sec-Fetch-Mode": "cors", + "Sec-Fetch-Site": "same-origin", + } + async with ClientSession( + headers=headers + ) as session: + data = { + "messages": messages, + "temperature": 0.6, + "stream": True, + **kwargs + } + async with session.post("https://ava-alpha-api.codelink.io/api/chat", json=data) as response: + response.raise_for_status() + async for line in response.content: + line = line.decode() + if line.startswith("data: "): + if line.startswith("data: [DONE]"): + break + line = json.loads(line[6:-1]) + + content = line["choices"][0]["delta"].get("content") + if content: + yield content \ No newline at end of file diff --git a/g4f/Provider/deprecated/Cromicle.py b/g4f/Provider/deprecated/Cromicle.py new file mode 100644 index 00000000..9f986cb5 --- /dev/null +++ b/g4f/Provider/deprecated/Cromicle.py @@ -0,0 +1,50 @@ +from __future__ import annotations + +from aiohttp import ClientSession +from hashlib import sha256 +from ...typing import AsyncResult, Messages, Dict + +from ..base_provider import AsyncGeneratorProvider +from ..helper import format_prompt + + +class Cromicle(AsyncGeneratorProvider): + url: str = 'https://cromicle.top' + working: bool = False + supports_gpt_35_turbo: bool = True + + @classmethod + async def create_async_generator( + cls, + model: str, + messages: Messages, + proxy: str = None, + **kwargs + ) -> AsyncResult: + async with ClientSession( + headers=_create_header() + ) as session: + async with session.post( + f'{cls.url}/chat', + proxy=proxy, + json=_create_payload(format_prompt(messages)) + ) as response: + response.raise_for_status() + async for stream in response.content.iter_any(): + if stream: + yield stream.decode() + + +def _create_header() -> Dict[str, str]: + return { + 'accept': '*/*', + 'content-type': 'application/json', + } + + +def _create_payload(message: str) -> Dict[str, str]: + return { + 'message': message, + 'token': 'abc', + 'hash': sha256('abc'.encode() + message.encode()).hexdigest() + } \ No newline at end of file diff --git a/g4f/Provider/deprecated/DfeHub.py b/g4f/Provider/deprecated/DfeHub.py new file mode 100644 index 00000000..e6d13444 --- /dev/null +++ b/g4f/Provider/deprecated/DfeHub.py @@ -0,0 +1,62 @@ +from __future__ import annotations + +import json +import re +import time + +import requests + +from ...typing import Any, CreateResult +from ..base_provider import AbstractProvider + + +class DfeHub(AbstractProvider): + url = "https://chat.dfehub.com/" + supports_stream = True + supports_gpt_35_turbo = True + + @staticmethod + def create_completion( + model: str, + messages: list[dict[str, str]], + stream: bool, **kwargs: Any) -> CreateResult: + + headers = { + "authority" : "chat.dfehub.com", + "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", + "content-type" : "application/json", + "origin" : "https://chat.dfehub.com", + "referer" : "https://chat.dfehub.com/", + "sec-ch-ua" : '"Not.A/Brand";v="8", "Chromium";v="114", "Google Chrome";v="114"', + "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/114.0.0.0 Safari/537.36", + "x-requested-with" : "XMLHttpRequest", + } + + json_data = { + "messages" : messages, + "model" : "gpt-3.5-turbo", + "temperature" : kwargs.get("temperature", 0.5), + "presence_penalty" : kwargs.get("presence_penalty", 0), + "frequency_penalty" : kwargs.get("frequency_penalty", 0), + "top_p" : kwargs.get("top_p", 1), + "stream" : True + } + + response = requests.post("https://chat.dfehub.com/api/openai/v1/chat/completions", + headers=headers, json=json_data, timeout=3) + + for chunk in response.iter_lines(): + if b"detail" in chunk: + delay = re.findall(r"\d+\.\d+", chunk.decode()) + delay = float(delay[-1]) + time.sleep(delay) + yield from DfeHub.create_completion(model, messages, stream, **kwargs) + if b"content" in chunk: + data = json.loads(chunk.decode().split("data: ")[1]) + yield (data["choices"][0]["delta"]["content"]) diff --git a/g4f/Provider/deprecated/EasyChat.py b/g4f/Provider/deprecated/EasyChat.py new file mode 100644 index 00000000..7a00f523 --- /dev/null +++ b/g4f/Provider/deprecated/EasyChat.py @@ -0,0 +1,89 @@ +from __future__ import annotations + +import json +import random +import requests + +from ...typing import Any, CreateResult +from ..base_provider import AbstractProvider + + +class EasyChat(AbstractProvider): + url: str = "https://free.easychat.work" + supports_stream = True + supports_gpt_35_turbo = True + working = False + + @staticmethod + def create_completion( + model: str, + messages: list[dict[str, str]], + stream: bool, **kwargs: Any) -> CreateResult: + + active_servers = [ + "https://chat10.fastgpt.me", + "https://chat9.fastgpt.me", + "https://chat1.fastgpt.me", + "https://chat2.fastgpt.me", + "https://chat3.fastgpt.me", + "https://chat4.fastgpt.me", + "https://gxos1h1ddt.fastgpt.me" + ] + + server = active_servers[kwargs.get("active_server", random.randint(0, 5))] + headers = { + "authority" : f"{server}".replace("https://", ""), + "accept" : "text/event-stream", + "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,fa=0.2", + "content-type" : "application/json", + "origin" : f"{server}", + "referer" : f"{server}/", + "x-requested-with" : "XMLHttpRequest", + 'plugins' : '0', + 'sec-ch-ua' : '"Chromium";v="116", "Not)A;Brand";v="24", "Google Chrome";v="116"', + 'sec-ch-ua-mobile' : '?0', + 'sec-ch-ua-platform': '"Windows"', + 'sec-fetch-dest' : 'empty', + 'sec-fetch-mode' : 'cors', + 'sec-fetch-site' : 'same-origin', + 'user-agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36', + 'usesearch' : 'false', + 'x-requested-with' : 'XMLHttpRequest' + } + + json_data = { + "messages" : messages, + "stream" : stream, + "model" : model, + "temperature" : kwargs.get("temperature", 0.5), + "presence_penalty" : kwargs.get("presence_penalty", 0), + "frequency_penalty" : kwargs.get("frequency_penalty", 0), + "top_p" : kwargs.get("top_p", 1) + } + + session = requests.Session() + # init cookies from server + session.get(f"{server}/") + + response = session.post(f"{server}/api/openai/v1/chat/completions", + headers=headers, json=json_data, stream=stream) + + if response.status_code != 200: + raise Exception(f"Error {response.status_code} from server : {response.reason}") + if not stream: + json_data = response.json() + + if "choices" in json_data: + yield json_data["choices"][0]["message"]["content"] + else: + raise Exception("No response from server") + + else: + + for chunk in response.iter_lines(): + + if b"content" in chunk: + splitData = chunk.decode().split("data:") + + if len(splitData) > 1: + yield json.loads(splitData[1])["choices"][0]["delta"]["content"] \ No newline at end of file diff --git a/g4f/Provider/deprecated/Equing.py b/g4f/Provider/deprecated/Equing.py new file mode 100644 index 00000000..5fd9797b --- /dev/null +++ b/g4f/Provider/deprecated/Equing.py @@ -0,0 +1,71 @@ +from __future__ import annotations + +import json +from abc import ABC, abstractmethod + +import requests + +from ...typing import Any, CreateResult +from ..base_provider import AbstractProvider + + +class Equing(AbstractProvider): + url: str = 'https://next.eqing.tech/' + working = False + supports_stream = True + supports_gpt_35_turbo = True + supports_gpt_4 = False + + @staticmethod + @abstractmethod + def create_completion( + model: str, + messages: list[dict[str, str]], + stream: bool, **kwargs: Any) -> CreateResult: + + headers = { + 'authority' : 'next.eqing.tech', + 'accept' : 'text/event-stream', + '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', + 'origin' : 'https://next.eqing.tech', + 'plugins' : '0', + 'pragma' : 'no-cache', + 'referer' : 'https://next.eqing.tech/', + 'sec-ch-ua' : '"Not/A)Brand";v="99", "Google Chrome";v="115", "Chromium";v="115"', + '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/115.0.0.0 Safari/537.36', + 'usesearch' : 'false', + 'x-requested-with' : 'XMLHttpRequest' + } + + json_data = { + 'messages' : messages, + 'stream' : stream, + 'model' : model, + 'temperature' : kwargs.get('temperature', 0.5), + 'presence_penalty' : kwargs.get('presence_penalty', 0), + 'frequency_penalty' : kwargs.get('frequency_penalty', 0), + 'top_p' : kwargs.get('top_p', 1), + } + + response = requests.post('https://next.eqing.tech/api/openai/v1/chat/completions', + headers=headers, json=json_data, stream=stream) + + if not stream: + yield response.json()["choices"][0]["message"]["content"] + return + + for line in response.iter_content(chunk_size=1024): + if line: + if b'content' in line: + line_json = json.loads(line.decode('utf-8').split('data: ')[1]) + + token = line_json['choices'][0]['delta'].get('content') + if token: + yield token \ No newline at end of file diff --git a/g4f/Provider/deprecated/FakeGpt.py b/g4f/Provider/deprecated/FakeGpt.py new file mode 100644 index 00000000..99b6bb1a --- /dev/null +++ b/g4f/Provider/deprecated/FakeGpt.py @@ -0,0 +1,91 @@ +from __future__ import annotations + +import uuid, time, random, json +from aiohttp import ClientSession + +from ...typing import AsyncResult, Messages +from ..base_provider import AsyncGeneratorProvider +from ..helper import format_prompt, get_random_string + + +class FakeGpt(AsyncGeneratorProvider): + url = "https://chat-shared2.zhile.io" + supports_gpt_35_turbo = True + working = False + _access_token = None + _cookie_jar = None + + @classmethod + async def create_async_generator( + cls, + model: str, + messages: Messages, + proxy: str = None, + **kwargs + ) -> AsyncResult: + headers = { + "Accept-Language": "en-US", + "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36", + "Referer": "https://chat-shared2.zhile.io/?v=2", + "sec-ch-ua": '"Google Chrome";v="117", "Not;A=Brand";v="8", "Chromium";v="117"', + "sec-ch-ua-platform": '"Linux"', + "sec-ch-ua-mobile": "?0", + } + async with ClientSession(headers=headers, cookie_jar=cls._cookie_jar) as session: + if not cls._access_token: + async with session.get(f"{cls.url}/api/loads", params={"t": int(time.time())}, proxy=proxy) as response: + response.raise_for_status() + list = (await response.json())["loads"] + token_ids = [t["token_id"] for t in list] + data = { + "token_key": random.choice(token_ids), + "session_password": get_random_string() + } + async with session.post(f"{cls.url}/auth/login", data=data, proxy=proxy) as response: + response.raise_for_status() + async with session.get(f"{cls.url}/api/auth/session", proxy=proxy) as response: + response.raise_for_status() + cls._access_token = (await response.json())["accessToken"] + cls._cookie_jar = session.cookie_jar + headers = { + "Content-Type": "application/json", + "Accept": "text/event-stream", + "X-Authorization": f"Bearer {cls._access_token}", + } + prompt = format_prompt(messages) + data = { + "action": "next", + "messages": [ + { + "id": str(uuid.uuid4()), + "author": {"role": "user"}, + "content": {"content_type": "text", "parts": [prompt]}, + "metadata": {}, + } + ], + "parent_message_id": str(uuid.uuid4()), + "model": "text-davinci-002-render-sha", + "plugin_ids": [], + "timezone_offset_min": -120, + "suggestions": [], + "history_and_training_disabled": True, + "arkose_token": "", + "force_paragen": False, + } + last_message = "" + async with session.post(f"{cls.url}/api/conversation", json=data, headers=headers, proxy=proxy) as response: + async for line in response.content: + if line.startswith(b"data: "): + line = line[6:] + if line == b"[DONE]": + break + try: + line = json.loads(line) + if line["message"]["metadata"]["message_type"] == "next": + new_message = line["message"]["content"]["parts"][0] + yield new_message[len(last_message):] + last_message = new_message + except: + continue + if not last_message: + raise RuntimeError("No valid response") \ No newline at end of file diff --git a/g4f/Provider/deprecated/FastGpt.py b/g4f/Provider/deprecated/FastGpt.py new file mode 100644 index 00000000..6a79d9aa --- /dev/null +++ b/g4f/Provider/deprecated/FastGpt.py @@ -0,0 +1,76 @@ +from __future__ import annotations + +import json +import random +import requests + +from ...typing import Any, CreateResult +from ..base_provider import AbstractProvider + + +class FastGpt(AbstractProvider): + url: str = 'https://chat9.fastgpt.me/' + working = False + needs_auth = False + supports_stream = True + supports_gpt_35_turbo = True + supports_gpt_4 = False + + @staticmethod + def create_completion( + model: str, + messages: list[dict[str, str]], + stream: bool, **kwargs: Any) -> CreateResult: + + headers = { + 'authority' : 'chat9.fastgpt.me', + 'accept' : 'text/event-stream', + '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', + 'origin' : 'https://chat9.fastgpt.me', + 'plugins' : '0', + 'pragma' : 'no-cache', + 'referer' : 'https://chat9.fastgpt.me/', + 'sec-ch-ua' : '"Not/A)Brand";v="99", "Google Chrome";v="115", "Chromium";v="115"', + '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/115.0.0.0 Safari/537.36', + 'usesearch' : 'false', + 'x-requested-with' : 'XMLHttpRequest', + } + + json_data = { + 'messages' : messages, + 'stream' : stream, + 'model' : model, + 'temperature' : kwargs.get('temperature', 0.5), + 'presence_penalty' : kwargs.get('presence_penalty', 0), + 'frequency_penalty' : kwargs.get('frequency_penalty', 0), + 'top_p' : kwargs.get('top_p', 1), + } + + subdomain = random.choice([ + 'jdaen979ew', + 'chat9' + ]) + + response = requests.post(f'https://{subdomain}.fastgpt.me/api/openai/v1/chat/completions', + headers=headers, json=json_data, stream=stream) + + for line in response.iter_lines(): + if line: + try: + if b'content' in line: + line_json = json.loads(line.decode('utf-8').split('data: ')[1]) + token = line_json['choices'][0]['delta'].get( + 'content' + ) + + if token: + yield token + except: + continue \ No newline at end of file diff --git a/g4f/Provider/deprecated/Forefront.py b/g4f/Provider/deprecated/Forefront.py new file mode 100644 index 00000000..39654b2c --- /dev/null +++ b/g4f/Provider/deprecated/Forefront.py @@ -0,0 +1,40 @@ +from __future__ import annotations + +import json + +import requests + +from ...typing import Any, CreateResult +from ..base_provider import AbstractProvider + + +class Forefront(AbstractProvider): + url = "https://forefront.com" + supports_stream = True + supports_gpt_35_turbo = True + + @staticmethod + def create_completion( + model: str, + messages: list[dict[str, str]], + stream: bool, **kwargs: Any) -> CreateResult: + + json_data = { + "text" : messages[-1]["content"], + "action" : "noauth", + "id" : "", + "parentId" : "", + "workspaceId" : "", + "messagePersona": "607e41fe-95be-497e-8e97-010a59b2e2c0", + "model" : "gpt-4", + "messages" : messages[:-1] if len(messages) > 1 else [], + "internetMode" : "auto", + } + + response = requests.post("https://streaming.tenant-forefront-default.knative.chi.coreweave.com/free-chat", + json=json_data, stream=True) + + response.raise_for_status() + for token in response.iter_lines(): + if b"delta" in token: + yield json.loads(token.decode().split("data: ")[1])["delta"] diff --git a/g4f/Provider/deprecated/GPTalk.py b/g4f/Provider/deprecated/GPTalk.py new file mode 100644 index 00000000..5b36d37b --- /dev/null +++ b/g4f/Provider/deprecated/GPTalk.py @@ -0,0 +1,87 @@ +from __future__ import annotations + +import secrets, time, json +from aiohttp import ClientSession + +from ...typing import AsyncResult, Messages +from ..base_provider import AsyncGeneratorProvider +from ..helper import format_prompt + + +class GPTalk(AsyncGeneratorProvider): + url = "https://gptalk.net" + working = False + supports_gpt_35_turbo = True + _auth = None + used_times = 0 + + @classmethod + async def create_async_generator( + cls, + model: str, + messages: Messages, + proxy: str = None, + **kwargs + ) -> AsyncResult: + if not model: + model = "gpt-3.5-turbo" + timestamp = int(time.time()) + headers = { + 'authority': 'gptalk.net', + 'accept': '*/*', + 'accept-language': 'de-DE,de;q=0.9,en-DE;q=0.8,en;q=0.7,en-US;q=0.6,nl;q=0.5,zh-CN;q=0.4,zh-TW;q=0.3,zh;q=0.2', + 'content-type': 'application/json', + 'origin': 'https://gptalk.net', + 'sec-ch-ua': '"Google Chrome";v="117", "Not;A=Brand";v="8", "Chromium";v="117"', + '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/117.0.0.0 Safari/537.36', + 'x-auth-appid': '2229', + 'x-auth-openid': '', + 'x-auth-platform': '', + 'x-auth-timestamp': f"{timestamp}", + } + async with ClientSession(headers=headers) as session: + if not cls._auth or cls._auth["expires_at"] < timestamp or cls.used_times == 5: + data = { + "fingerprint": secrets.token_hex(16).zfill(32), + "platform": "fingerprint" + } + async with session.post(f"{cls.url}/api/chatgpt/user/login", json=data, proxy=proxy) as response: + response.raise_for_status() + cls._auth = (await response.json())["data"] + cls.used_times = 0 + data = { + "content": format_prompt(messages), + "accept": "stream", + "from": 1, + "model": model, + "is_mobile": 0, + "user_agent": headers["user-agent"], + "is_open_ctx": 0, + "prompt": "", + "roid": 111, + "temperature": 0, + "ctx_msg_count": 3, + "created_at": timestamp + } + headers = { + 'authorization': f'Bearer {cls._auth["token"]}', + } + async with session.post(f"{cls.url}/api/chatgpt/chatapi/text", json=data, headers=headers, proxy=proxy) as response: + response.raise_for_status() + token = (await response.json())["data"]["token"] + cls.used_times += 1 + last_message = "" + async with session.get(f"{cls.url}/api/chatgpt/chatapi/stream", params={"token": token}, proxy=proxy) as response: + response.raise_for_status() + async for line in response.content: + if line.startswith(b"data: "): + if line.startswith(b"data: [DONE]"): + break + message = json.loads(line[6:-1])["content"] + yield message[len(last_message):] + last_message = message diff --git a/g4f/Provider/deprecated/GeekGpt.py b/g4f/Provider/deprecated/GeekGpt.py new file mode 100644 index 00000000..7a460083 --- /dev/null +++ b/g4f/Provider/deprecated/GeekGpt.py @@ -0,0 +1,73 @@ +from __future__ import annotations +import requests, json + +from ..base_provider import AbstractProvider +from ...typing import CreateResult, Messages +from json import dumps + + +class GeekGpt(AbstractProvider): + url = 'https://chat.geekgpt.org' + working = False + supports_message_history = True + supports_stream = True + supports_gpt_35_turbo = True + supports_gpt_4 = True + + @classmethod + def create_completion( + cls, + model: str, + messages: Messages, + stream: bool, + **kwargs + ) -> CreateResult: + if not model: + model = "gpt-3.5-turbo" + json_data = { + 'messages': messages, + 'model': model, + 'temperature': kwargs.get('temperature', 0.9), + 'presence_penalty': kwargs.get('presence_penalty', 0), + 'top_p': kwargs.get('top_p', 1), + 'frequency_penalty': kwargs.get('frequency_penalty', 0), + 'stream': True + } + + data = dumps(json_data, separators=(',', ':')) + + headers = { + 'authority': 'ai.fakeopen.com', + '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', + 'authorization': 'Bearer pk-this-is-a-real-free-pool-token-for-everyone', + 'content-type': 'application/json', + 'origin': 'https://chat.geekgpt.org', + 'referer': 'https://chat.geekgpt.org/', + 'sec-ch-ua': '"Chromium";v="118", "Google Chrome";v="118", "Not=A?Brand";v="99"', + 'sec-ch-ua-mobile': '?0', + 'sec-ch-ua-platform': '"macOS"', + 'sec-fetch-dest': 'empty', + 'sec-fetch-mode': 'cors', + 'sec-fetch-site': 'cross-site', + 'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36', + } + + response = requests.post("https://ai.fakeopen.com/v1/chat/completions", + headers=headers, data=data, stream=True) + response.raise_for_status() + + for chunk in response.iter_lines(): + if b'content' in chunk: + json_data = chunk.decode().replace("data: ", "") + + if json_data == "[DONE]": + break + + try: + content = json.loads(json_data)["choices"][0]["delta"].get("content") + except Exception as e: + raise RuntimeError(f'error | {e} :', json_data) + + if content: + yield content \ No newline at end of file diff --git a/g4f/Provider/deprecated/GetGpt.py b/g4f/Provider/deprecated/GetGpt.py new file mode 100644 index 00000000..dd586569 --- /dev/null +++ b/g4f/Provider/deprecated/GetGpt.py @@ -0,0 +1,77 @@ +from __future__ import annotations + +import json +import os +import uuid + +import requests +# try: +# from Crypto.Cipher import AES +# except ImportError: +# from Cryptodome.Cipher import AES + +from ...typing import Any, CreateResult +from ..base_provider import AbstractProvider + + +class GetGpt(AbstractProvider): + url = 'https://chat.getgpt.world/' + supports_stream = True + working = False + supports_gpt_35_turbo = True + + @staticmethod + def create_completion( + model: str, + messages: list[dict[str, str]], + stream: bool, **kwargs: Any) -> CreateResult: + + headers = { + 'Content-Type' : 'application/json', + 'Referer' : 'https://chat.getgpt.world/', + 'user-agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36', + } + + data = json.dumps( + { + 'messages' : messages, + 'frequency_penalty' : kwargs.get('frequency_penalty', 0), + 'max_tokens' : kwargs.get('max_tokens', 4000), + 'model' : 'gpt-3.5-turbo', + 'presence_penalty' : kwargs.get('presence_penalty', 0), + 'temperature' : kwargs.get('temperature', 1), + 'top_p' : kwargs.get('top_p', 1), + 'stream' : True, + 'uuid' : str(uuid.uuid4()) + } + ) + + res = requests.post('https://chat.getgpt.world/api/chat/stream', + headers=headers, json={'signature': _encrypt(data)}, stream=True) + + res.raise_for_status() + for line in res.iter_lines(): + if b'content' in line: + line_json = json.loads(line.decode('utf-8').split('data: ')[1]) + yield (line_json['choices'][0]['delta']['content']) + + +def _encrypt(e: str): + # t = os.urandom(8).hex().encode('utf-8') + # n = os.urandom(8).hex().encode('utf-8') + # r = e.encode('utf-8') + + # cipher = AES.new(t, AES.MODE_CBC, n) + # ciphertext = cipher.encrypt(_pad_data(r)) + + # return ciphertext.hex() + t.decode('utf-8') + n.decode('utf-8') + return + + +def _pad_data(data: bytes) -> bytes: + # block_size = AES.block_size + # padding_size = block_size - len(data) % block_size + # padding = bytes([padding_size] * padding_size) + + # return data + padding + return \ No newline at end of file diff --git a/g4f/Provider/deprecated/H2o.py b/g4f/Provider/deprecated/H2o.py new file mode 100644 index 00000000..ba4ca507 --- /dev/null +++ b/g4f/Provider/deprecated/H2o.py @@ -0,0 +1,89 @@ +from __future__ import annotations + +import json +import uuid + +from aiohttp import ClientSession + +from ...typing import AsyncResult, Messages +from ..base_provider import AsyncGeneratorProvider, format_prompt + + +class H2o(AsyncGeneratorProvider): + url = "https://gpt-gm.h2o.ai" + model = "h2oai/h2ogpt-gm-oasst1-en-2048-falcon-40b-v1" + + @classmethod + async def create_async_generator( + cls, + model: str, + messages: Messages, + proxy: str = None, + **kwargs + ) -> AsyncResult: + model = model if model else cls.model + headers = {"Referer": f"{cls.url}/"} + + async with ClientSession( + headers=headers + ) as session: + data = { + "ethicsModalAccepted": "true", + "shareConversationsWithModelAuthors": "true", + "ethicsModalAcceptedAt": "", + "activeModel": model, + "searchEnabled": "true", + } + async with session.post( + f"{cls.url}/settings", + proxy=proxy, + data=data + ) as response: + response.raise_for_status() + + async with session.post( + f"{cls.url}/conversation", + proxy=proxy, + json={"model": model}, + ) as response: + response.raise_for_status() + conversationId = (await response.json())["conversationId"] + + data = { + "inputs": format_prompt(messages), + "parameters": { + "temperature": 0.4, + "truncate": 2048, + "max_new_tokens": 1024, + "do_sample": True, + "repetition_penalty": 1.2, + "return_full_text": False, + **kwargs + }, + "stream": True, + "options": { + "id": str(uuid.uuid4()), + "response_id": str(uuid.uuid4()), + "is_retry": False, + "use_cache": False, + "web_search_id": "", + }, + } + async with session.post( + f"{cls.url}/conversation/{conversationId}", + proxy=proxy, + json=data + ) as response: + start = "data:" + async for line in response.content: + line = line.decode("utf-8") + if line and line.startswith(start): + line = json.loads(line[len(start):-1]) + if not line["token"]["special"]: + yield line["token"]["text"] + + async with session.delete( + f"{cls.url}/conversation/{conversationId}", + proxy=proxy, + ) as response: + response.raise_for_status() \ No newline at end of file diff --git a/g4f/Provider/deprecated/Hashnode.py b/g4f/Provider/deprecated/Hashnode.py new file mode 100644 index 00000000..c2c0ffb7 --- /dev/null +++ b/g4f/Provider/deprecated/Hashnode.py @@ -0,0 +1,80 @@ +from __future__ import annotations + +from aiohttp import ClientSession + +from ...typing import AsyncResult, Messages +from ..base_provider import AsyncGeneratorProvider +from ..helper import get_random_hex + +class SearchTypes(): + quick = "quick" + code = "code" + websearch = "websearch" + +class Hashnode(AsyncGeneratorProvider): + url = "https://hashnode.com" + working = False + supports_message_history = True + supports_gpt_35_turbo = True + _sources = [] + + @classmethod + async def create_async_generator( + cls, + model: str, + messages: Messages, + search_type: str = SearchTypes.websearch, + 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", + "Referer": f"{cls.url}/rix", + "Content-Type": "application/json", + "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: + prompt = messages[-1]["content"] + cls._sources = [] + if search_type == "websearch": + async with session.post( + f"{cls.url}/api/ai/rix/search", + json={"prompt": prompt}, + proxy=proxy, + ) as response: + response.raise_for_status() + cls._sources = (await response.json())["result"] + data = { + "chatId": get_random_hex(), + "history": messages, + "prompt": prompt, + "searchType": search_type, + "urlToScan": None, + "searchResults": cls._sources, + } + async with session.post( + f"{cls.url}/api/ai/rix/completion", + json=data, + proxy=proxy, + ) as response: + response.raise_for_status() + async for chunk in response.content.iter_any(): + if chunk: + yield chunk.decode() + + @classmethod + def get_sources(cls) -> list: + return [{ + "title": source["name"], + "url": source["url"] + } for source in cls._sources] \ No newline at end of file diff --git a/g4f/Provider/deprecated/Lockchat.py b/g4f/Provider/deprecated/Lockchat.py new file mode 100644 index 00000000..edab0bd4 --- /dev/null +++ b/g4f/Provider/deprecated/Lockchat.py @@ -0,0 +1,54 @@ +from __future__ import annotations + +import json + +import requests + +from ...typing import Any, CreateResult +from ..base_provider import AbstractProvider + + +class Lockchat(AbstractProvider): + url: str = "http://supertest.lockchat.app" + supports_stream = True + supports_gpt_35_turbo = True + supports_gpt_4 = True + + @staticmethod + def create_completion( + model: str, + messages: list[dict[str, str]], + stream: bool, **kwargs: Any) -> CreateResult: + + temperature = float(kwargs.get("temperature", 0.7)) + payload = { + "temperature": temperature, + "messages" : messages, + "model" : model, + "stream" : True, + } + + headers = { + "user-agent": "ChatX/39 CFNetwork/1408.0.4 Darwin/22.5.0", + } + response = requests.post("http://supertest.lockchat.app/v1/chat/completions", + json=payload, headers=headers, stream=True) + + response.raise_for_status() + for token in response.iter_lines(): + if b"The model: `gpt-4` does not exist" in token: + print("error, retrying...") + + Lockchat.create_completion( + model = model, + messages = messages, + stream = stream, + temperature = temperature, + **kwargs) + + if b"content" in token: + token = json.loads(token.decode("utf-8").split("data: ")[1]) + token = token["choices"][0]["delta"].get("content") + + if token: + yield (token) \ No newline at end of file diff --git a/g4f/Provider/deprecated/Myshell.py b/g4f/Provider/deprecated/Myshell.py new file mode 100644 index 00000000..2487440d --- /dev/null +++ b/g4f/Provider/deprecated/Myshell.py @@ -0,0 +1,165 @@ +# not using WS anymore + +from __future__ import annotations + +import json, uuid, hashlib, time, random + +from aiohttp import ClientSession +from aiohttp.http import WSMsgType +import asyncio + +from ...typing import AsyncResult, Messages +from ..base_provider import AsyncGeneratorProvider, format_prompt + + +models = { + "samantha": "1e3be7fe89e94a809408b1154a2ee3e1", + "gpt-3.5-turbo": "8077335db7cd47e29f7de486612cc7fd", + "gpt-4": "01c8de4fbfc548df903712b0922a4e01", +} + + +class Myshell(AsyncGeneratorProvider): + url = "https://app.myshell.ai/chat" + working = False + supports_gpt_35_turbo = True + supports_gpt_4 = True + + @classmethod + async def create_async_generator( + cls, + model: str, + messages: Messages, + proxy: str = None, + timeout: int = 90, + **kwargs + ) -> AsyncResult: + if not model: + bot_id = models["samantha"] + elif model in models: + bot_id = models[model] + else: + raise ValueError(f"Model are not supported: {model}") + + user_agent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36' + visitor_id = generate_visitor_id(user_agent) + + async with ClientSession( + headers={'User-Agent': user_agent} + ) as session: + async with session.ws_connect( + "wss://api.myshell.ai/ws/?EIO=4&transport=websocket", + autoping=False, + timeout=timeout, + proxy=proxy + ) as wss: + # Send and receive hello message + await wss.receive_str() + message = json.dumps({"token": None, "visitorId": visitor_id}) + await wss.send_str(f"40/chat,{message}") + await wss.receive_str() + + # Fix "need_verify_captcha" issue + await asyncio.sleep(5) + + # Create chat message + text = format_prompt(messages) + chat_data = json.dumps(["text_chat",{ + "reqId": str(uuid.uuid4()), + "botUid": bot_id, + "sourceFrom": "myshellWebsite", + "text": text, + **generate_signature(text) + }]) + + # Send chat message + chat_start = "42/chat," + chat_message = f"{chat_start}{chat_data}" + await wss.send_str(chat_message) + + # Receive messages + async for message in wss: + if message.type != WSMsgType.TEXT: + continue + # Ping back + if message.data == "2": + await wss.send_str("3") + continue + # Is not chat message + if not message.data.startswith(chat_start): + continue + data_type, data = json.loads(message.data[len(chat_start):]) + if data_type == "text_stream": + if data["data"]["text"]: + yield data["data"]["text"] + elif data["data"]["isFinal"]: + break + elif data_type in ("message_replied", "need_verify_captcha"): + raise RuntimeError(f"Received unexpected message: {data_type}") + + +def generate_timestamp() -> str: + return str( + int( + str(int(time.time() * 1000))[:-1] + + str( + sum( + 2 * int(digit) + if idx % 2 == 0 + else 3 * int(digit) + for idx, digit in enumerate(str(int(time.time() * 1000))[:-1]) + ) + % 10 + ) + ) + ) + +def generate_signature(text: str): + timestamp = generate_timestamp() + version = 'v1.0.0' + secret = '8@VXGK3kKHr!u2gA' + data = f"{version}#{text}#{timestamp}#{secret}" + signature = hashlib.md5(data.encode()).hexdigest() + signature = signature[::-1] + return { + "signature": signature, + "timestamp": timestamp, + "version": version + } + +def xor_hash(B: str): + r = [] + i = 0 + + def o(e, t): + o_val = 0 + for i in range(len(t)): + o_val |= r[i] << (8 * i) + return e ^ o_val + + for e in range(len(B)): + t = ord(B[e]) + r.insert(0, 255 & t) + + if len(r) >= 4: + i = o(i, r) + r = [] + + if len(r) > 0: + i = o(i, r) + + return hex(i)[2:] + +def performance() -> str: + t = int(time.time() * 1000) + e = 0 + while t == int(time.time() * 1000): + e += 1 + return hex(t)[2:] + hex(e)[2:] + +def generate_visitor_id(user_agent: str) -> str: + f = performance() + r = hex(int(random.random() * (16**16)))[2:-2] + d = xor_hash(user_agent) + e = hex(1080 * 1920)[2:] + return f"{f}-{r}-{d}-{e}-{f}" \ No newline at end of file diff --git a/g4f/Provider/deprecated/NoowAi.py b/g4f/Provider/deprecated/NoowAi.py new file mode 100644 index 00000000..dba87273 --- /dev/null +++ b/g4f/Provider/deprecated/NoowAi.py @@ -0,0 +1,66 @@ +from __future__ import annotations + +import json +from aiohttp import ClientSession + +from ..typing import AsyncResult, Messages +from .base_provider import AsyncGeneratorProvider +from .helper import get_random_string + +class NoowAi(AsyncGeneratorProvider): + url = "https://noowai.com" + supports_message_history = True + supports_gpt_35_turbo = True + working = False + + @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", + "Referer": f"{cls.url}/", + "Content-Type": "application/json", + "Origin": cls.url, + "Alt-Used": "noowai.com", + "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: + data = { + "botId": "default", + "customId": "d49bc3670c3d858458576d75c8ea0f5d", + "session": "N/A", + "chatId": get_random_string(), + "contextId": 25, + "messages": messages, + "newMessage": messages[-1]["content"], + "stream": True + } + async with session.post(f"{cls.url}/wp-json/mwai-ui/v1/chats/submit", json=data, proxy=proxy) as response: + response.raise_for_status() + async for line in response.content: + if line.startswith(b"data: "): + try: + line = json.loads(line[6:]) + assert "type" in line + except: + raise RuntimeError(f"Broken line: {line.decode()}") + if line["type"] == "live": + yield line["data"] + elif line["type"] == "end": + break + elif line["type"] == "error": + raise RuntimeError(line["data"]) \ No newline at end of file diff --git a/g4f/Provider/deprecated/Opchatgpts.py b/g4f/Provider/deprecated/Opchatgpts.py new file mode 100644 index 00000000..94b1d099 --- /dev/null +++ b/g4f/Provider/deprecated/Opchatgpts.py @@ -0,0 +1,59 @@ +from __future__ import annotations + +import random, string, json +from aiohttp import ClientSession + +from ...typing import Messages, AsyncResult +from ..base_provider import AsyncGeneratorProvider +from ..helper import get_random_string + +class Opchatgpts(AsyncGeneratorProvider): + url = "https://opchatgpts.net" + working = False + supports_message_history = True + supports_gpt_35_turbo = True + + @classmethod + async def create_async_generator( + cls, + model: str, + messages: Messages, + proxy: str = None, **kwargs) -> AsyncResult: + + headers = { + "User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36", + "Accept" : "*/*", + "Accept-Language" : "de,en-US;q=0.7,en;q=0.3", + "Origin" : cls.url, + "Alt-Used" : "opchatgpts.net", + "Referer" : f"{cls.url}/chatgpt-free-use/", + "Sec-Fetch-Dest" : "empty", + "Sec-Fetch-Mode" : "cors", + "Sec-Fetch-Site" : "same-origin", + } + async with ClientSession( + headers=headers + ) as session: + data = { + "botId": "default", + "chatId": get_random_string(), + "contextId": 28, + "customId": None, + "messages": messages, + "newMessage": messages[-1]["content"], + "session": "N/A", + "stream": True + } + async with session.post(f"{cls.url}/wp-json/mwai-ui/v1/chats/submit", json=data, proxy=proxy) as response: + response.raise_for_status() + async for line in response.content: + if line.startswith(b"data: "): + try: + line = json.loads(line[6:]) + assert "type" in line + except: + raise RuntimeError(f"Broken line: {line.decode()}") + if line["type"] == "live": + yield line["data"] + elif line["type"] == "end": + break \ No newline at end of file diff --git a/g4f/Provider/deprecated/OpenAssistant.py b/g4f/Provider/deprecated/OpenAssistant.py new file mode 100644 index 00000000..80cae3c2 --- /dev/null +++ b/g4f/Provider/deprecated/OpenAssistant.py @@ -0,0 +1,88 @@ +from __future__ import annotations + +import json + +from aiohttp import ClientSession + +from ...typing import AsyncResult, Messages +from ..base_provider import AsyncGeneratorProvider +from ..helper import format_prompt, get_cookies + +class OpenAssistant(AsyncGeneratorProvider): + url = "https://open-assistant.io/chat" + needs_auth = True + working = False + model = "OA_SFT_Llama_30B_6" + + @classmethod + async def create_async_generator( + cls, + model: str, + messages: Messages, + proxy: str = None, + cookies: dict = None, + **kwargs + ) -> AsyncResult: + if not cookies: + cookies = get_cookies("open-assistant.io") + + headers = { + 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36', + } + async with ClientSession( + cookies=cookies, + headers=headers + ) as session: + async with session.post("https://open-assistant.io/api/chat", proxy=proxy) as response: + chat_id = (await response.json())["id"] + + data = { + "chat_id": chat_id, + "content": f"[INST]\n{format_prompt(messages)}\n[/INST]", + "parent_id": None + } + async with session.post("https://open-assistant.io/api/chat/prompter_message", proxy=proxy, json=data) as response: + parent_id = (await response.json())["id"] + + data = { + "chat_id": chat_id, + "parent_id": parent_id, + "model_config_name": model if model else cls.model, + "sampling_parameters":{ + "top_k": 50, + "top_p": None, + "typical_p": None, + "temperature": 0.35, + "repetition_penalty": 1.1111111111111112, + "max_new_tokens": 1024, + **kwargs + }, + "plugins":[] + } + async with session.post("https://open-assistant.io/api/chat/assistant_message", proxy=proxy, json=data) as response: + data = await response.json() + if "id" in data: + message_id = data["id"] + elif "message" in data: + raise RuntimeError(data["message"]) + else: + response.raise_for_status() + + params = { + 'chat_id': chat_id, + 'message_id': message_id, + } + async with session.post("https://open-assistant.io/api/chat/events", proxy=proxy, params=params) as response: + start = "data: " + async for line in response.content: + line = line.decode("utf-8") + if line and line.startswith(start): + line = json.loads(line[len(start):]) + if line["event_type"] == "token": + yield line["text"] + + params = { + 'chat_id': chat_id, + } + async with session.delete("https://open-assistant.io/api/chat", proxy=proxy, params=params) as response: + response.raise_for_status() diff --git a/g4f/Provider/deprecated/Phind.py b/g4f/Provider/deprecated/Phind.py new file mode 100644 index 00000000..c72bf09e --- /dev/null +++ b/g4f/Provider/deprecated/Phind.py @@ -0,0 +1,140 @@ +from __future__ import annotations + +import re +import json +from urllib import parse +from datetime import datetime + +from ...typing import AsyncResult, Messages +from ..base_provider import AsyncGeneratorProvider +from ...requests import StreamSession + +class Phind(AsyncGeneratorProvider): + url = "https://www.phind.com" + working = False + lockdown = True + supports_stream = True + supports_message_history = True + + @classmethod + async def create_async_generator( + cls, + model: str, + messages: Messages, + proxy: str = None, + timeout: int = 120, + creative_mode: bool = False, + **kwargs + ) -> AsyncResult: + headers = { + "Accept": "*/*", + "Origin": cls.url, + "Referer": f"{cls.url}/search", + "Sec-Fetch-Dest": "empty", + "Sec-Fetch-Mode": "cors", + "Sec-Fetch-Site": "same-origin", + } + async with StreamSession( + headers=headers, + impersonate="chrome", + proxies={"https": proxy}, + timeout=timeout + ) as session: + url = "https://www.phind.com/search?home=true" + async with session.get(url) as response: + text = await response.text() + match = re.search(r'', text) + data = json.loads(match.group("json")) + challenge_seeds = data["props"]["pageProps"]["challengeSeeds"] + + prompt = messages[-1]["content"] + data = { + "question": prompt, + "question_history": [ + message["content"] for message in messages[:-1] if message["role"] == "user" + ], + "answer_history": [ + message["content"] for message in messages if message["role"] == "assistant" + ], + "webResults": [], + "options": { + "date": datetime.now().strftime("%d.%m.%Y"), + "language": "en-US", + "detailed": True, + "anonUserId": "", + "answerModel": "GPT-4" if model.startswith("gpt-4") else "Phind-34B", + "creativeMode": creative_mode, + "customLinks": [] + }, + "context": "\n".join([message["content"] for message in messages if message["role"] == "system"]), + } + data["challenge"] = generate_challenge(data, **challenge_seeds) + async with session.post(f"https://https.api.phind.com/infer/", headers=headers, json=data) as response: + new_line = False + async for line in response.iter_lines(): + if line.startswith(b"data: "): + chunk = line[6:] + if chunk.startswith(b''): + break + if chunk.startswith(b''): + raise RuntimeError(f"Response: {chunk.decode()}") + if chunk.startswith(b'') or chunk.startswith(b''): + pass + elif chunk.startswith(b"") or chunk.startswith(b""): + pass + elif chunk.startswith(b"") or chunk.startswith(b""): + pass + elif chunk: + yield chunk.decode() + elif new_line: + yield "\n" + new_line = False + else: + new_line = True + +def deterministic_stringify(obj): + def handle_value(value): + if isinstance(value, (dict, list)): + if isinstance(value, list): + return '[' + ','.join(sorted(map(handle_value, value))) + ']' + else: # It's a dict + return '{' + deterministic_stringify(value) + '}' + elif isinstance(value, bool): + return 'true' if value else 'false' + elif isinstance(value, (int, float)): + return format(value, '.8f').rstrip('0').rstrip('.') + elif isinstance(value, str): + return f'"{value}"' + else: + return 'null' + + items = sorted(obj.items(), key=lambda x: x[0]) + return ','.join([f'{k}:{handle_value(v)}' for k, v in items if handle_value(v) is not None]) + +def prng_general(seed, multiplier, addend, modulus): + a = seed * multiplier + addend + if a < 0: + return ((a%modulus)-modulus)/modulus + else: + return a%modulus/modulus + +def generate_challenge_seed(l): + I = deterministic_stringify(l) + d = parse.quote(I, safe='') + return simple_hash(d) + +def simple_hash(s): + d = 0 + for char in s: + if len(char) > 1 or ord(char) >= 256: + continue + d = ((d << 5) - d + ord(char[0])) & 0xFFFFFFFF + if d > 0x7FFFFFFF: # 2147483647 + d -= 0x100000000 # Subtract 2**32 + return d + +def generate_challenge(obj, **kwargs): + return prng_general( + seed=generate_challenge_seed(obj), + **kwargs + ) \ No newline at end of file diff --git a/g4f/Provider/deprecated/V50.py b/g4f/Provider/deprecated/V50.py new file mode 100644 index 00000000..456445f7 --- /dev/null +++ b/g4f/Provider/deprecated/V50.py @@ -0,0 +1,61 @@ +from __future__ import annotations + +import uuid + +import requests + +from ...typing import Any, CreateResult +from ..base_provider import AbstractProvider + + +class V50(AbstractProvider): + url = 'https://p5.v50.ltd' + supports_gpt_35_turbo = True + supports_stream = False + needs_auth = False + working = False + + @staticmethod + def create_completion( + model: str, + messages: list[dict[str, str]], + stream: bool, **kwargs: Any) -> CreateResult: + + conversation = ( + "\n".join( + f"{message['role']}: {message['content']}" for message in messages + ) + + "\nassistant: " + ) + payload = { + "prompt" : conversation, + "options" : {}, + "systemMessage" : ".", + "temperature" : kwargs.get("temperature", 0.4), + "top_p" : kwargs.get("top_p", 0.4), + "model" : model, + "user" : str(uuid.uuid4()) + } + + headers = { + 'authority' : 'p5.v50.ltd', + 'accept' : 'application/json, text/plain, */*', + 'accept-language' : 'id-ID,id;q=0.9,en-US;q=0.8,en;q=0.7', + 'content-type' : 'application/json', + 'origin' : 'https://p5.v50.ltd', + 'referer' : 'https://p5.v50.ltd/', + 'sec-ch-ua-platform': '"Windows"', + 'sec-fetch-dest' : 'empty', + 'sec-fetch-mode' : 'cors', + 'sec-fetch-site' : 'same-origin', + 'user-agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36' + } + response = requests.post( + "https://p5.v50.ltd/api/chat-process", + json=payload, + headers=headers, + proxies=kwargs.get('proxy', {}), + ) + + if "https://fk1.v50.ltd" not in response.text: + yield response.text \ No newline at end of file diff --git a/g4f/Provider/deprecated/Vercel.py b/g4f/Provider/deprecated/Vercel.py new file mode 100644 index 00000000..adf7b208 --- /dev/null +++ b/g4f/Provider/deprecated/Vercel.py @@ -0,0 +1,392 @@ +from __future__ import annotations + +import json, base64, requests, random, uuid + +try: + import execjs + has_requirements = True +except ImportError: + has_requirements = False + +from ...typing import Messages, TypedDict, CreateResult, Any +from ..base_provider import AbstractProvider +from ...errors import MissingRequirementsError + +class Vercel(AbstractProvider): + url = 'https://sdk.vercel.ai' + working = False + supports_message_history = True + supports_gpt_35_turbo = True + supports_stream = True + + @staticmethod + def create_completion( + model: str, + messages: Messages, + stream: bool, + proxy: str = None, + **kwargs + ) -> CreateResult: + if not has_requirements: + raise MissingRequirementsError('Install "PyExecJS" package') + + if not model: + model = "gpt-3.5-turbo" + elif model not in model_info: + raise ValueError(f"Vercel does not support {model}") + + 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', + 'content-type': 'application/json', + 'custom-encoding': get_anti_bot_token(), + 'origin': 'https://sdk.vercel.ai', + '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', + } + + json_data = { + 'model' : model_info[model]['id'], + 'messages' : messages, + 'playgroundId': str(uuid.uuid4()), + 'chatIndex' : 0, + **model_info[model]['default_params'], + **kwargs + } + + max_retries = kwargs.get('max_retries', 20) + for _ in range(max_retries): + response = requests.post('https://chat.vercel.ai/api/chat', + headers=headers, json=json_data, stream=True, proxies={"https": proxy}) + try: + response.raise_for_status() + except: + continue + for token in response.iter_content(chunk_size=None): + yield token.decode() + break + + +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://sdk.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 `${this}`}; + return (%s)(%s)''' % (raw_data['c'], raw_data['a']) + + raw_token = json.dumps({'r': execjs.compile(js_script).call(''), 't': raw_data['t']}, + separators = (",", ":")) + + return base64.b64encode(raw_token.encode('utf-16le')).decode() + +class ModelInfo(TypedDict): + id: str + default_params: dict[str, Any] + +model_info: dict[str, ModelInfo] = { + # 'claude-instant-v1': { + # 'id': 'anthropic:claude-instant-v1', + # 'default_params': { + # 'temperature': 1, + # 'maximumLength': 1024, + # 'topP': 1, + # 'topK': 1, + # 'presencePenalty': 1, + # 'frequencyPenalty': 1, + # 'stopSequences': ['\n\nHuman:'], + # }, + # }, + # 'claude-v1': { + # 'id': 'anthropic:claude-v1', + # 'default_params': { + # 'temperature': 1, + # 'maximumLength': 1024, + # 'topP': 1, + # 'topK': 1, + # 'presencePenalty': 1, + # 'frequencyPenalty': 1, + # 'stopSequences': ['\n\nHuman:'], + # }, + # }, + # 'claude-v2': { + # 'id': 'anthropic:claude-v2', + # 'default_params': { + # 'temperature': 1, + # 'maximumLength': 1024, + # 'topP': 1, + # 'topK': 1, + # 'presencePenalty': 1, + # 'frequencyPenalty': 1, + # 'stopSequences': ['\n\nHuman:'], + # }, + # }, + 'replicate/llama70b-v2-chat': { + 'id': 'replicate:replicate/llama-2-70b-chat', + 'default_params': { + 'temperature': 0.75, + 'maximumLength': 3000, + 'topP': 1, + 'repetitionPenalty': 1, + }, + }, + 'a16z-infra/llama7b-v2-chat': { + 'id': 'replicate:a16z-infra/llama7b-v2-chat', + 'default_params': { + 'temperature': 0.75, + 'maximumLength': 3000, + 'topP': 1, + 'repetitionPenalty': 1, + }, + }, + 'a16z-infra/llama13b-v2-chat': { + 'id': 'replicate:a16z-infra/llama13b-v2-chat', + 'default_params': { + 'temperature': 0.75, + 'maximumLength': 3000, + 'topP': 1, + 'repetitionPenalty': 1, + }, + }, + 'replicate/llama-2-70b-chat': { + 'id': 'replicate:replicate/llama-2-70b-chat', + 'default_params': { + 'temperature': 0.75, + 'maximumLength': 3000, + 'topP': 1, + 'repetitionPenalty': 1, + }, + }, + 'bigscience/bloom': { + 'id': 'huggingface:bigscience/bloom', + 'default_params': { + 'temperature': 0.5, + 'maximumLength': 1024, + 'topP': 0.95, + 'topK': 4, + 'repetitionPenalty': 1.03, + }, + }, + 'google/flan-t5-xxl': { + 'id': 'huggingface:google/flan-t5-xxl', + 'default_params': { + 'temperature': 0.5, + 'maximumLength': 1024, + 'topP': 0.95, + 'topK': 4, + 'repetitionPenalty': 1.03, + }, + }, + 'EleutherAI/gpt-neox-20b': { + 'id': 'huggingface:EleutherAI/gpt-neox-20b', + 'default_params': { + 'temperature': 0.5, + 'maximumLength': 1024, + 'topP': 0.95, + 'topK': 4, + 'repetitionPenalty': 1.03, + 'stopSequences': [], + }, + }, + 'OpenAssistant/oasst-sft-4-pythia-12b-epoch-3.5': { + 'id': 'huggingface:OpenAssistant/oasst-sft-4-pythia-12b-epoch-3.5', + 'default_params': { + 'maximumLength': 1024, + 'typicalP': 0.2, + 'repetitionPenalty': 1, + }, + }, + 'OpenAssistant/oasst-sft-1-pythia-12b': { + 'id': 'huggingface:OpenAssistant/oasst-sft-1-pythia-12b', + 'default_params': { + 'maximumLength': 1024, + 'typicalP': 0.2, + 'repetitionPenalty': 1, + }, + }, + 'bigcode/santacoder': { + 'id': 'huggingface:bigcode/santacoder', + 'default_params': { + 'temperature': 0.5, + 'maximumLength': 1024, + 'topP': 0.95, + 'topK': 4, + 'repetitionPenalty': 1.03, + }, + }, + 'command-light-nightly': { + 'id': 'cohere:command-light-nightly', + 'default_params': { + 'temperature': 0.9, + 'maximumLength': 1024, + 'topP': 1, + 'topK': 0, + 'presencePenalty': 0, + 'frequencyPenalty': 0, + 'stopSequences': [], + }, + }, + 'command-nightly': { + 'id': 'cohere:command-nightly', + 'default_params': { + 'temperature': 0.9, + 'maximumLength': 1024, + 'topP': 1, + 'topK': 0, + 'presencePenalty': 0, + 'frequencyPenalty': 0, + 'stopSequences': [], + }, + }, + # 'gpt-4': { + # 'id': 'openai:gpt-4', + # 'default_params': { + # 'temperature': 0.7, + # 'maximumLength': 8192, + # 'topP': 1, + # 'presencePenalty': 0, + # 'frequencyPenalty': 0, + # 'stopSequences': [], + # }, + # }, + # 'gpt-4-0613': { + # 'id': 'openai:gpt-4-0613', + # 'default_params': { + # 'temperature': 0.7, + # 'maximumLength': 8192, + # 'topP': 1, + # 'presencePenalty': 0, + # 'frequencyPenalty': 0, + # 'stopSequences': [], + # }, + # }, + 'code-davinci-002': { + 'id': 'openai:code-davinci-002', + 'default_params': { + 'temperature': 0.5, + 'maximumLength': 1024, + 'topP': 1, + 'presencePenalty': 0, + 'frequencyPenalty': 0, + 'stopSequences': [], + }, + }, + 'gpt-3.5-turbo': { + 'id': 'openai:gpt-3.5-turbo', + 'default_params': { + 'temperature': 0.7, + 'maximumLength': 4096, + 'topP': 1, + 'topK': 1, + 'presencePenalty': 1, + 'frequencyPenalty': 1, + 'stopSequences': [], + }, + }, + 'gpt-3.5-turbo-16k': { + 'id': 'openai:gpt-3.5-turbo-16k', + 'default_params': { + 'temperature': 0.7, + 'maximumLength': 16280, + 'topP': 1, + 'topK': 1, + 'presencePenalty': 1, + 'frequencyPenalty': 1, + 'stopSequences': [], + }, + }, + 'gpt-3.5-turbo-16k-0613': { + 'id': 'openai:gpt-3.5-turbo-16k-0613', + 'default_params': { + 'temperature': 0.7, + 'maximumLength': 16280, + 'topP': 1, + 'topK': 1, + 'presencePenalty': 1, + 'frequencyPenalty': 1, + 'stopSequences': [], + }, + }, + 'text-ada-001': { + 'id': 'openai:text-ada-001', + 'default_params': { + 'temperature': 0.5, + 'maximumLength': 1024, + 'topP': 1, + 'presencePenalty': 0, + 'frequencyPenalty': 0, + 'stopSequences': [], + }, + }, + 'text-babbage-001': { + 'id': 'openai:text-babbage-001', + 'default_params': { + 'temperature': 0.5, + 'maximumLength': 1024, + 'topP': 1, + 'presencePenalty': 0, + 'frequencyPenalty': 0, + 'stopSequences': [], + }, + }, + 'text-curie-001': { + 'id': 'openai:text-curie-001', + 'default_params': { + 'temperature': 0.5, + 'maximumLength': 1024, + 'topP': 1, + 'presencePenalty': 0, + 'frequencyPenalty': 0, + 'stopSequences': [], + }, + }, + 'text-davinci-002': { + 'id': 'openai:text-davinci-002', + 'default_params': { + 'temperature': 0.5, + 'maximumLength': 1024, + 'topP': 1, + 'presencePenalty': 0, + 'frequencyPenalty': 0, + 'stopSequences': [], + }, + }, + 'text-davinci-003': { + 'id': 'openai:text-davinci-003', + 'default_params': { + 'temperature': 0.5, + 'maximumLength': 4097, + 'topP': 1, + 'presencePenalty': 0, + 'frequencyPenalty': 0, + 'stopSequences': [], + }, + }, +} \ No newline at end of file diff --git a/g4f/Provider/deprecated/Vitalentum.py b/g4f/Provider/deprecated/Vitalentum.py new file mode 100644 index 00000000..8f466a52 --- /dev/null +++ b/g4f/Provider/deprecated/Vitalentum.py @@ -0,0 +1,55 @@ +from __future__ import annotations + +import json +from aiohttp import ClientSession + +from ..base_provider import AsyncGeneratorProvider +from ...typing import AsyncResult, Messages + +class Vitalentum(AsyncGeneratorProvider): + url = "https://app.vitalentum.io" + supports_gpt_35_turbo = True + + + @classmethod + async def create_async_generator( + cls, + model: str, + messages: Messages, + proxy: str = None, + **kwargs + ) -> AsyncResult: + headers = { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36", + "Accept": "text/event-stream", + "Accept-language": "de,en-US;q=0.7,en;q=0.3", + "Origin": cls.url, + "Referer": f"{cls.url}/", + "Sec-Fetch-Dest": "empty", + "Sec-Fetch-Mode": "cors", + "Sec-Fetch-Site": "same-origin", + } + conversation = json.dumps({"history": [{ + "speaker": "human" if message["role"] == "user" else "bot", + "text": message["content"], + } for message in messages]}) + data = { + "conversation": conversation, + "temperature": 0.7, + **kwargs + } + async with ClientSession( + headers=headers + ) as session: + async with session.post(f"{cls.url}/api/converse-edge", json=data, proxy=proxy) as response: + response.raise_for_status() + async for line in response.content: + line = line.decode() + if line.startswith("data: "): + if line.startswith("data: [DONE]"): + break + line = json.loads(line[6:-1]) + content = line["choices"][0]["delta"].get("content") + + if content: + yield content \ No newline at end of file diff --git a/g4f/Provider/deprecated/VoiGpt.py b/g4f/Provider/deprecated/VoiGpt.py new file mode 100644 index 00000000..9b061e63 --- /dev/null +++ b/g4f/Provider/deprecated/VoiGpt.py @@ -0,0 +1,91 @@ +from __future__ import annotations + +import json +import requests +from ..base_provider import AbstractProvider +from ...typing import Messages, CreateResult + + +class VoiGpt(AbstractProvider): + """ + VoiGpt - A provider for VoiGpt.com + + **Note** : to use this provider you have to get your csrf token/cookie from the voigpt.com website + + Args: + model: The model to use + messages: The messages to send + stream: Whether to stream the response + proxy: The proxy to use + access_token: The access token to use + **kwargs: Additional keyword arguments + + Returns: + A CreateResult object + """ + url = "https://voigpt.com" + working = False + supports_gpt_35_turbo = True + supports_message_history = True + supports_stream = False + _access_token: str = None + + @classmethod + def create_completion( + cls, + model: str, + messages: Messages, + stream: bool, + proxy: str = None, + access_token: str = None, + **kwargs + ) -> CreateResult: + + if not model: + model = "gpt-3.5-turbo" + if not access_token: + access_token = cls._access_token + if not access_token: + headers = { + "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", + "accept-language": "de-DE,de;q=0.9,en-DE;q=0.8,en;q=0.7,en-US;q=0.6", + "sec-ch-ua": "\"Google Chrome\";v=\"119\", \"Chromium\";v=\"119\", \"Not?A_Brand\";v=\"24\"", + "sec-ch-ua-mobile": "?0", + "sec-ch-ua-platform": "\"Linux\"", + "sec-fetch-dest": "document", + "sec-fetch-mode": "navigate", + "sec-fetch-site": "none", + "sec-fetch-user": "?1", + "upgrade-insecure-requests": "1", + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36", + } + req_response = requests.get(cls.url, headers=headers) + access_token = cls._access_token = req_response.cookies.get("csrftoken") + + headers = { + "Accept-Encoding": "gzip, deflate, br", + "Accept-Language": "de-DE,de;q=0.9,en-DE;q=0.8,en;q=0.7,en-US;q=0.6", + "Cookie": f"csrftoken={access_token};", + "Origin": "https://voigpt.com", + "Referer": "https://voigpt.com/", + "Sec-Ch-Ua": "'Google Chrome';v='119', 'Chromium';v='119', 'Not?A_Brand';v='24'", + "Sec-Ch-Ua-Mobile": "?0", + "Sec-Ch-Ua-Platform": "'Windows'", + "Sec-Fetch-Dest": "empty", + "Sec-Fetch-Mode": "cors", + "Sec-Fetch-Site": "same-origin", + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36", + "X-Csrftoken": access_token, + } + + payload = { + "messages": messages, + } + request_url = f"{cls.url}/generate_response/" + req_response = requests.post(request_url, headers=headers, json=payload) + try: + response = json.loads(req_response.text) + yield response["response"] + except: + raise RuntimeError(f"Response: {req_response.text}") + diff --git a/g4f/Provider/deprecated/Wewordle.py b/g4f/Provider/deprecated/Wewordle.py new file mode 100644 index 00000000..c30887fb --- /dev/null +++ b/g4f/Provider/deprecated/Wewordle.py @@ -0,0 +1,65 @@ +from __future__ import annotations + +import random, string, time +from aiohttp import ClientSession + +from ..base_provider import AsyncProvider + + +class Wewordle(AsyncProvider): + url = "https://wewordle.org" + working = False + supports_gpt_35_turbo = True + + @classmethod + async def create_async( + cls, + model: str, + messages: list[dict[str, str]], + proxy: str = None, + **kwargs + ) -> str: + + headers = { + "accept" : "*/*", + "pragma" : "no-cache", + "Content-Type" : "application/json", + "Connection" : "keep-alive" + } + + _user_id = "".join(random.choices(f"{string.ascii_lowercase}{string.digits}", k=16)) + _app_id = "".join(random.choices(f"{string.ascii_lowercase}{string.digits}", k=31)) + _request_date = time.strftime("%Y-%m-%dT%H:%M:%S.000Z", time.gmtime()) + data = { + "user" : _user_id, + "messages" : messages, + "subscriber": { + "originalPurchaseDate" : None, + "originalApplicationVersion" : None, + "allPurchaseDatesMillis" : {}, + "entitlements" : {"active": {}, "all": {}}, + "allPurchaseDates" : {}, + "allExpirationDatesMillis" : {}, + "allExpirationDates" : {}, + "originalAppUserId" : f"$RCAnonymousID:{_app_id}", + "latestExpirationDate" : None, + "requestDate" : _request_date, + "latestExpirationDateMillis" : None, + "nonSubscriptionTransactions" : [], + "originalPurchaseDateMillis" : None, + "managementURL" : None, + "allPurchasedProductIdentifiers": [], + "firstSeen" : _request_date, + "activeSubscriptions" : [], + } + } + + + async with ClientSession( + headers=headers + ) as session: + async with session.post(f"{cls.url}/gptapi/v1/android/turbo", proxy=proxy, json=data) as response: + response.raise_for_status() + content = (await response.json())["message"]["content"] + if content: + return content \ No newline at end of file diff --git a/g4f/Provider/deprecated/Wuguokai.py b/g4f/Provider/deprecated/Wuguokai.py new file mode 100644 index 00000000..f12d1bfe --- /dev/null +++ b/g4f/Provider/deprecated/Wuguokai.py @@ -0,0 +1,57 @@ +from __future__ import annotations + +import random + +import requests + +from ...typing import Any, CreateResult +from ..base_provider import AbstractProvider, format_prompt + + +class Wuguokai(AbstractProvider): + url = 'https://chat.wuguokai.xyz' + supports_gpt_35_turbo = True + working = False + + @staticmethod + def create_completion( + model: str, + messages: list[dict[str, str]], + stream: bool, + **kwargs: Any, + ) -> CreateResult: + headers = { + 'authority': 'ai-api.wuguokai.xyz', + 'accept': 'application/json, text/plain, */*', + 'accept-language': 'id-ID,id;q=0.9,en-US;q=0.8,en;q=0.7', + 'content-type': 'application/json', + 'origin': 'https://chat.wuguokai.xyz', + 'referer': 'https://chat.wuguokai.xyz/', + 'sec-ch-ua': '"Not.A/Brand";v="8", "Chromium";v="114", "Google Chrome";v="114"', + 'sec-ch-ua-mobile': '?0', + 'sec-ch-ua-platform': '"Windows"', + 'sec-fetch-dest': 'empty', + 'sec-fetch-mode': 'cors', + 'sec-fetch-site': 'same-site', + 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36' + } + data ={ + "prompt": format_prompt(messages), + "options": {}, + "userId": f"#/chat/{random.randint(1,99999999)}", + "usingContext": True + } + response = requests.post( + "https://ai-api20.wuguokai.xyz/api/chat-process", + headers=headers, + timeout=3, + json=data, + proxies=kwargs.get('proxy', {}), + ) + _split = response.text.split("> 若回答失败请重试或多刷新几次界面后重试") + if response.status_code != 200: + raise Exception(f"Error: {response.status_code} {response.reason}") + if len(_split) > 1: + yield _split[1].strip() + else: + yield _split[0].strip() \ No newline at end of file diff --git a/g4f/Provider/deprecated/Ylokh.py b/g4f/Provider/deprecated/Ylokh.py new file mode 100644 index 00000000..dbff4602 --- /dev/null +++ b/g4f/Provider/deprecated/Ylokh.py @@ -0,0 +1,58 @@ +from __future__ import annotations + +import json + +from ...requests import StreamSession +from ..base_provider import AsyncGeneratorProvider +from ...typing import AsyncResult, Messages + +class Ylokh(AsyncGeneratorProvider): + url = "https://chat.ylokh.xyz" + working = False + supports_message_history = True + supports_gpt_35_turbo = True + + + @classmethod + async def create_async_generator( + cls, + model: str, + messages: Messages, + stream: bool = True, + proxy: str = None, + timeout: int = 120, + **kwargs + ) -> AsyncResult: + model = model if model else "gpt-3.5-turbo" + headers = {"Origin": cls.url, "Referer": f"{cls.url}/"} + data = { + "messages": messages, + "model": model, + "temperature": 1, + "presence_penalty": 0, + "top_p": 1, + "frequency_penalty": 0, + "allow_fallback": True, + "stream": stream, + **kwargs + } + async with StreamSession( + headers=headers, + proxies={"https": proxy}, + timeout=timeout + ) as session: + async with session.post("https://chatapi.ylokh.xyz/v1/chat/completions", json=data) as response: + response.raise_for_status() + if stream: + async for line in response.iter_lines(): + line = line.decode() + if line.startswith("data: "): + if line.startswith("data: [DONE]"): + break + line = json.loads(line[6:]) + content = line["choices"][0]["delta"].get("content") + if content: + yield content + else: + chat = await response.json() + yield chat["choices"][0]["message"].get("content") \ No newline at end of file diff --git a/g4f/Provider/deprecated/Yqcloud.py b/g4f/Provider/deprecated/Yqcloud.py new file mode 100644 index 00000000..227f8995 --- /dev/null +++ b/g4f/Provider/deprecated/Yqcloud.py @@ -0,0 +1,61 @@ +from __future__ import annotations + +import random +from ...requests import StreamSession + +from ...typing import AsyncResult, Messages +from ..base_provider import AsyncGeneratorProvider, format_prompt + + +class Yqcloud(AsyncGeneratorProvider): + url = "https://chat9.yqcloud.top/" + working = False + supports_gpt_35_turbo = True + + @staticmethod + async def create_async_generator( + model: str, + messages: Messages, + proxy: str = None, + timeout: int = 120, + **kwargs, + ) -> AsyncResult: + async with StreamSession( + headers=_create_header(), proxies={"https": proxy}, timeout=timeout + ) as session: + payload = _create_payload(messages, **kwargs) + async with session.post("https://api.aichatos.cloud/api/generateStream", json=payload) as response: + response.raise_for_status() + async for chunk in response.iter_content(): + if chunk: + chunk = chunk.decode() + if "sorry, 您的ip已由于触发防滥用检测而被封禁" in chunk: + raise RuntimeError("IP address is blocked by abuse detection.") + yield chunk + + +def _create_header(): + return { + "accept" : "application/json, text/plain, */*", + "content-type" : "application/json", + "origin" : "https://chat9.yqcloud.top", + "referer" : "https://chat9.yqcloud.top/" + } + + +def _create_payload( + messages: Messages, + system_message: str = "", + user_id: int = None, + **kwargs +): + if not user_id: + user_id = random.randint(1690000544336, 2093025544336) + return { + "prompt": format_prompt(messages), + "network": True, + "system": system_message, + "withoutContext": False, + "stream": True, + "userId": f"#/chat/{user_id}" + } diff --git a/g4f/Provider/deprecated/__init__.py b/g4f/Provider/deprecated/__init__.py new file mode 100644 index 00000000..bf923f2a --- /dev/null +++ b/g4f/Provider/deprecated/__init__.py @@ -0,0 +1,35 @@ +from .AiService import AiService +from .CodeLinkAva import CodeLinkAva +from .DfeHub import DfeHub +from .EasyChat import EasyChat +from .Forefront import Forefront +from .GetGpt import GetGpt +from .Lockchat import Lockchat +from .Wewordle import Wewordle +from .Equing import Equing +from .Wuguokai import Wuguokai +from .V50 import V50 +from .FastGpt import FastGpt +from .Aivvm import Aivvm +from .Vitalentum import Vitalentum +from .H2o import H2o +from .Myshell import Myshell +from .Acytoo import Acytoo +from .Aibn import Aibn +from .Ails import Ails +from .ChatgptDuo import ChatgptDuo +from .Cromicle import Cromicle +from .Opchatgpts import Opchatgpts +from .Yqcloud import Yqcloud +from .Aichat import Aichat +from .Berlin import Berlin +from .Phind import Phind +from .AiAsk import AiAsk +from ..AiChatOnline import AiChatOnline +from .ChatAnywhere import ChatAnywhere +from .FakeGpt import FakeGpt +from .GeekGpt import GeekGpt +from .GPTalk import GPTalk +from .Hashnode import Hashnode +from .Ylokh import Ylokh +from .OpenAssistant import OpenAssistant \ No newline at end of file -- cgit v1.2.3 From 1e62a9dd60d69de636845497ffe9512fe60dfa2a Mon Sep 17 00:00:00 2001 From: kqlio67 Date: Wed, 25 Sep 2024 20:05:39 +0300 Subject: feat(g4f/Provider/HuggingChat.py): update model list and aliases --- g4f/Provider/HuggingChat.py | 12 ++++++------ g4f/models.py | 29 +++++++++++++++++++++-------- 2 files changed, 27 insertions(+), 14 deletions(-) (limited to 'g4f') diff --git a/g4f/Provider/HuggingChat.py b/g4f/Provider/HuggingChat.py index 01490e2f..488a1114 100644 --- a/g4f/Provider/HuggingChat.py +++ b/g4f/Provider/HuggingChat.py @@ -18,9 +18,9 @@ class HuggingChat(AbstractProvider, ProviderModelMixin): 'CohereForAI/c4ai-command-r-plus-08-2024', 'Qwen/Qwen2.5-72B-Instruct', 'mistralai/Mixtral-8x7B-Instruct-v0.1', - 'NousResearch/Nous-Hermes-2-Mixtral-8x7B-DPO', - 'mistralai/Mistral-7B-Instruct-v0.3', - 'microsoft/Phi-3-mini-4k-instruct', + 'NousResearch/Hermes-3-Llama-3.1-8B', + 'mistralai/Mistral-Nemo-Instruct-2407', + 'microsoft/Phi-3.5-mini-instruct', ] model_aliases = { @@ -28,9 +28,9 @@ class HuggingChat(AbstractProvider, ProviderModelMixin): "command-r-plus": "CohereForAI/c4ai-command-r-plus-08-2024", "qwen-2-72b": "Qwen/Qwen2.5-72B-Instruct", "mixtral-8x7b": "mistralai/Mixtral-8x7B-Instruct-v0.1", - "mixtral-8x7b-dpo": "NousResearch/Nous-Hermes-2-Mixtral-8x7B-DPO", - "mistral-7b": "mistralai/Mistral-7B-Instruct-v0.3", - "phi-3-mini-4k": "microsoft/Phi-3-mini-4k-instruct", + "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 diff --git a/g4f/models.py b/g4f/models.py index 2f4405a3..a6ff9e13 100644 --- a/g4f/models.py +++ b/g4f/models.py @@ -249,27 +249,39 @@ mixtral_8x22b = Model( best_provider = IterListProvider([DeepInfraChat, Airforce]) ) +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 = IterListProvider([HuggingChat, Airforce, HuggingFace]) + best_provider = IterListProvider([Airforce]) ) -### Microsoft ### -phi_3_mini_4k = Model( - name = "phi-3-mini-4k", - base_provider = "Microsoft", +hermes_3 = Model( + name = "hermes-3", + base_provider = "NousResearch", best_provider = IterListProvider([HuggingChat, HuggingFace]) ) + +### Microsoft ### phi_3_medium_4k = Model( name = "phi-3-medium-4k", base_provider = "Microsoft", best_provider = IterListProvider([DeepInfraChat]) ) +phi_3_5_mini = Model( + name = "phi-3.5-mini", + base_provider = "Microsoft", + best_provider = IterListProvider([HuggingChat, HuggingFace]) +) ### Google DeepMind ### # gemini @@ -800,18 +812,19 @@ class ModelUtils: 'mistral-7b': mistral_7b, 'mixtral-8x7b': mixtral_8x7b, 'mixtral-8x22b': mixtral_8x22b, +'mistral-nemo': mistral_nemo, ### NousResearch ### -'mixtral-8x7b-dpo': mixtral_8x7b_dpo, +'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 -- cgit v1.2.3 From b3ddad4a08921269cb24900fa6ebad2fe2209511 Mon Sep 17 00:00:00 2001 From: kqlio67 Date: Wed, 25 Sep 2024 20:44:55 +0300 Subject: feat(g4f/client/async_client.py): enhance image and chat response handling --- g4f/client/async_client.py | 322 ++++++++++++++++++++++----------------------- 1 file changed, 160 insertions(+), 162 deletions(-) (limited to 'g4f') diff --git a/g4f/client/async_client.py b/g4f/client/async_client.py index 2fe4640b..3ac77b41 100644 --- a/g4f/client/async_client.py +++ b/g4f/client/async_client.py @@ -1,32 +1,27 @@ 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 - -try: - anext -except NameError: - async def anext(iter): - async for chunk in iter: - return chunk +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 async def iter_response( response: AsyncIterator[str], @@ -34,30 +29,37 @@ async def iter_response( response_format: dict = None, max_tokens: int = None, stop: list = None -) -> AsyncIterResponse: +) -> AsyncIterator[ChatCompletion | ChatCompletionChunk]: content = "" finish_reason = None completion_id = ''.join(random.choices(string.ascii_letters + string.digits, k=28)) - count: int = 0 - async for chunk in response: + + async for idx, chunk in enumerate(response): if isinstance(chunk, FinishReason): finish_reason = chunk.reason break elif isinstance(chunk, BaseConversation): yield chunk continue + content += str(chunk) - count += 1 - if max_tokens is not None and count >= max_tokens: + + if max_tokens is not None and idx + 1 >= 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 +68,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 +82,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) + 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 + @property + def images(self) -> Images: + return self._images -class Completions(): +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 +118,156 @@ 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 = await 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) + + return response if stream else await anext(response) -class Chat(): +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())) + 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}") -def create_image(provider: ProviderType, prompt: str, model: str = "", **kwargs) -> AsyncIterator: 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(): +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 ProviderNotFoundError(f'Provider not found: {provider}') + 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") + if asyncio.iscoroutinefunction(provider.create): + response = await provider.create(prompt) + else: + 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) 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 + raise ValueError(f"Provider {provider} does not support image variation") - 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 NoImageResponseError("Failed to create image variation") -- cgit v1.2.3 From 85c95be22d571f68393be7130248dd910d06a8da Mon Sep 17 00:00:00 2001 From: kqlio67 Date: Wed, 25 Sep 2024 21:31:27 +0300 Subject: Restored old version(g4f/client/async_client.py) --- g4f/client/async_client.py | 322 +++++++++++++++++++++++---------------------- 1 file changed, 162 insertions(+), 160 deletions(-) (limited to 'g4f') diff --git a/g4f/client/async_client.py b/g4f/client/async_client.py index 3ac77b41..2fe4640b 100644 --- a/g4f/client/async_client.py +++ b/g4f/client/async_client.py @@ -1,27 +1,32 @@ from __future__ import annotations -import os import time import random import string -import logging import asyncio -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 -from ..errors import NoImageResponseError -from .stubs import ChatCompletion, ChatCompletionChunk, Image, ImagesResponse -from .image_models import ImageModels -from .types import IterResponse, ImageProvider +import base64 +from aiohttp import ClientSession, BaseConnector + 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 .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 ..providers.conversation import BaseConversation +from ..image import ImageResponse as ImageProviderResponse, ImageDataResponse + +try: + anext +except NameError: + async def anext(iter): + async for chunk in iter: + return chunk async def iter_response( response: AsyncIterator[str], @@ -29,37 +34,30 @@ async def iter_response( response_format: dict = None, max_tokens: int = None, stop: list = None -) -> AsyncIterator[ChatCompletion | ChatCompletionChunk]: +) -> AsyncIterResponse: content = "" finish_reason = None completion_id = ''.join(random.choices(string.ascii_letters + string.digits, k=28)) - - async for idx, chunk in enumerate(response): + count: int = 0 + async for chunk in response: if isinstance(chunk, FinishReason): finish_reason = chunk.reason break elif isinstance(chunk, BaseConversation): yield chunk continue - content += str(chunk) - - if max_tokens is not None and idx + 1 >= max_tokens: + count += 1 + if max_tokens is not None and count >= max_tokens: finish_reason = "length" - - first, content, chunk = find_stop(stop, content, chunk if stream else None) - + first, content, chunk = find_stop(stop, content, chunk) 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: @@ -68,12 +66,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: AsyncIterator) -> AsyncIterator: +async def iter_append_model_and_provider(response: AsyncIterResponse) -> AsyncIterResponse: 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): @@ -82,32 +80,59 @@ 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) + self.images: Images = Images(self, image_provider) - @property - def images(self) -> Images: - return self._images +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 -class Completions: +class Completions(): def __init__(self, client: AsyncClient, provider: ProviderType = None): self.client: AsyncClient = client self.provider: ProviderType = provider - async def create( + 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, - ignored: list[str] = None, + response_format: dict = None, + ignored : list[str] = None, ignore_working: bool = False, ignore_stream: bool = False, **kwargs @@ -118,156 +143,133 @@ class Completions: stream, ignored, ignore_working, - ignore_stream, + ignore_stream ) - stop = [stop] if isinstance(stop, str) else stop - - response = await 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 - ), + 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, **kwargs ) - 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) + return response if stream else anext(response) -class Chat: +class Chat(): completions: Completions def __init__(self, client: AsyncClient, provider: ProviderType = None): self.completions = Completions(client, provider) -async def iter_image_response(response: AsyncIterator) -> Union[ImagesResponse, None]: - logging.info("Starting iter_image_response") +async def iter_image_response( + response: AsyncIterator, + response_format: str = None, + connector: BaseConnector = None, + proxy: str = None +) -> Union[ImagesResponse, None]: async for chunk in response: - logging.info(f"Processing chunk: {chunk}") if isinstance(chunk, ImageProviderResponse): - 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 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: if isinstance(provider, type) and provider.__name__ == "You": kwargs["chat_mode"] = "create" else: - prompt = f"create an image with: {prompt}" - - response = await provider.create_completion( + prompt = f"create a image with: {prompt}" + return provider.create_async_generator( model, [{"role": "user", "content": prompt}], stream=True, - proxy=client.get_proxy(), **kwargs ) - - logging.info(f"Response from create_completion: {response}") - return response -class Images: +class Images(): def __init__(self, client: AsyncClient, provider: ImageProvider = None): self.client: AsyncClient = client self.provider: ImageProvider = provider self.models: ImageModels = ImageModels(client) - 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}") + def get_provider(self, model: str, provider: ProviderType = None): + if isinstance(provider, str): + if provider in ProviderUtils.convert: + provider = ProviderUtils.convert[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") - if asyncio.iscoroutinefunction(provider.create): - response = await provider.create(prompt) - else: - 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) + raise ProviderNotFoundError(f'Provider not found: {provider}') else: - raise ValueError(f"Provider {provider} does not support image generation") - - 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}") + provider = self.models.get(model, self.provider) + return provider - 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) + 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 + ) else: - raise ValueError(f"Provider {provider} does not support image variation") + 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 - raise NoImageResponseError("Failed to create image variation") + 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 -- cgit v1.2.3 From 9a16296416ab2c801aa2f5920cc1790d554ec1ce Mon Sep 17 00:00:00 2001 From: kqlio67 Date: Thu, 26 Sep 2024 21:38:04 +0300 Subject: feat(g4f/client/async_client.py): enhance image generation and logging --- g4f/client/async_client.py | 359 ++++++++++++++++++++++++--------------------- 1 file changed, 192 insertions(+), 167 deletions(-) (limited to 'g4f') 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") -- cgit v1.2.3 From 8237de5d63209d9b003407c1f6d72b8ffffe7f76 Mon Sep 17 00:00:00 2001 From: kqlio67 Date: Thu, 26 Sep 2024 22:40:40 +0300 Subject: Updated g4f/models.py g4f/Provider/HuggingChat.py --- g4f/Provider/HuggingChat.py | 2 -- g4f/models.py | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) (limited to 'g4f') diff --git a/g4f/Provider/HuggingChat.py b/g4f/Provider/HuggingChat.py index 488a1114..e6f70bed 100644 --- a/g4f/Provider/HuggingChat.py +++ b/g4f/Provider/HuggingChat.py @@ -17,7 +17,6 @@ class HuggingChat(AbstractProvider, ProviderModelMixin): 'meta-llama/Meta-Llama-3.1-70B-Instruct', 'CohereForAI/c4ai-command-r-plus-08-2024', 'Qwen/Qwen2.5-72B-Instruct', - 'mistralai/Mixtral-8x7B-Instruct-v0.1', 'NousResearch/Hermes-3-Llama-3.1-8B', 'mistralai/Mistral-Nemo-Instruct-2407', 'microsoft/Phi-3.5-mini-instruct', @@ -27,7 +26,6 @@ class HuggingChat(AbstractProvider, ProviderModelMixin): "llama-3.1-70b": "meta-llama/Meta-Llama-3.1-70B-Instruct", "command-r-plus": "CohereForAI/c4ai-command-r-plus-08-2024", "qwen-2-72b": "Qwen/Qwen2.5-72B-Instruct", - "mixtral-8x7b": "mistralai/Mixtral-8x7B-Instruct-v0.1", "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", diff --git a/g4f/models.py b/g4f/models.py index a6ff9e13..4d461ada 100644 --- a/g4f/models.py +++ b/g4f/models.py @@ -240,7 +240,7 @@ mistral_7b = Model( mixtral_8x7b = Model( name = "mixtral-8x7b", base_provider = "Mistral", - best_provider = IterListProvider([HuggingChat, DDG, ReplicateHome, DeepInfraChat, Airforce, DeepInfra, HuggingFace]) + best_provider = IterListProvider([DDG, ReplicateHome, DeepInfraChat, Airforce, DeepInfra]) ) mixtral_8x22b = Model( -- cgit v1.2.3 From 9ff384978c569de6876d162eacc643672157a028 Mon Sep 17 00:00:00 2001 From: kqlio67 Date: Fri, 27 Sep 2024 00:08:56 +0300 Subject: feat(g4f/Provider/AIChatFree.py): add AIChatFree provider --- g4f/Provider/AIChatFree.py | 76 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 g4f/Provider/AIChatFree.py (limited to 'g4f') 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() -- cgit v1.2.3 From cfe5acc15221806e9bc1155ef5d5f9e760f195a7 Mon Sep 17 00:00:00 2001 From: kqlio67 Date: Fri, 27 Sep 2024 00:24:44 +0300 Subject: Updated g4f/models.py g4f/Provider/Liaobots.py g4f/Provider/__init__.py g4f/Provider/DeepInfraChat.py --- g4f/Provider/DeepInfraChat.py | 6 ++--- g4f/Provider/Liaobots.py | 60 +++++++++++++++---------------------------- g4f/Provider/__init__.py | 1 + g4f/models.py | 25 +++--------------- 4 files changed, 27 insertions(+), 65 deletions(-) (limited to 'g4f') diff --git a/g4f/Provider/DeepInfraChat.py b/g4f/Provider/DeepInfraChat.py index fa6dd2fe..b8cc6ab8 100644 --- a/g4f/Provider/DeepInfraChat.py +++ b/g4f/Provider/DeepInfraChat.py @@ -39,7 +39,7 @@ class DeepInfraChat(AsyncGeneratorProvider, ProviderModelMixin): 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", + "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", @@ -47,9 +47,9 @@ class DeepInfraChat(AsyncGeneratorProvider, ProviderModelMixin): "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", + "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", + "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", diff --git a/g4f/Provider/Liaobots.py b/g4f/Provider/Liaobots.py index 598da5ea..b292020e 100644 --- a/g4f/Provider/Liaobots.py +++ b/g4f/Provider/Liaobots.py @@ -36,36 +36,18 @@ models = { "tokenLimit": 7800, "context": "8K", }, - "o1-preview": { - "id": "o1-preview", - "name": "o1-preview", - "model": "o1", - "provider": "OpenAI", - "maxLength": 400000, - "tokenLimit": 100000, - "context": "128K", - }, - "o1-mini": { - "id": "o1-mini", - "name": "o1-mini", - "model": "o1", - "provider": "OpenAI", - "maxLength": 400000, - "tokenLimit": 100000, - "context": "128K", - }, - "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, @@ -117,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, @@ -153,8 +135,8 @@ models = { "tokenLimit": 200000, "context": "200K", }, - "gemini-1.5-flash-exp-0827": { - "id": "gemini-1.5-flash-exp-0827", + "gemini-1.5-flash-002": { + "id": "gemini-1.5-flash-002", "name": "Gemini-1.5-Flash-1M", "model": "Gemini", "provider": "Google", @@ -162,8 +144,8 @@ models = { "tokenLimit": 1000000, "context": "1024K", }, - "gemini-1.5-pro-exp-0827": { - "id": "gemini-1.5-pro-exp-0827", + "gemini-1.5-pro-002": { + "id": "gemini-1.5-pro-002", "name": "Gemini-1.5-Pro-1M", "model": "Gemini", "provider": "Google", @@ -186,11 +168,9 @@ class Liaobots(AsyncGeneratorProvider, ProviderModelMixin): model_aliases = { "gpt-4o-mini": "gpt-4o-mini-free", "gpt-4o": "gpt-4o-free", - - "o1": "o1-preview", - - "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", @@ -201,8 +181,8 @@ class Liaobots(AsyncGeneratorProvider, ProviderModelMixin): "claude-3-haiku": "claude-3-haiku-20240307", "claude-2.1": "claude-2.1", - "gemini-flash": "gemini-1.5-flash-exp-0827", - "gemini-pro": "gemini-1.5-pro-exp-0827", + "gemini-flash": "gemini-1.5-flash-002", + "gemini-pro": "gemini-1.5-pro-002", } _auth_code = "" diff --git a/g4f/Provider/__init__.py b/g4f/Provider/__init__.py index 515f5912..d088b5ee 100644 --- a/g4f/Provider/__init__.py +++ b/g4f/Provider/__init__.py @@ -10,6 +10,7 @@ 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 diff --git a/g4f/models.py b/g4f/models.py index 4d461ada..bac83b5b 100644 --- a/g4f/models.py +++ b/g4f/models.py @@ -4,6 +4,7 @@ from dataclasses import dataclass from .Provider import IterListProvider, ProviderType from .Provider import ( + AIChatFree, Airforce, Allyfy, Bing, @@ -146,22 +147,6 @@ gpt_4 = Model( ]) ) -# o1 -o1 = Model( - name = 'o1', - base_provider = 'OpenAI', - best_provider = IterListProvider([ - Liaobots - ]) -) - -o1_mini = Model( - name = 'o1-mini', - base_provider = 'OpenAI', - best_provider = IterListProvider([ - Liaobots - ]) -) ### GigaChat ### gigachat = Model( @@ -288,7 +273,7 @@ phi_3_5_mini = Model( gemini_pro = Model( name = 'gemini-pro', base_provider = 'Google DeepMind', - best_provider = IterListProvider([GeminiPro, LiteIcoding, Blackbox, Liaobots, Airforce]) + best_provider = IterListProvider([GeminiPro, LiteIcoding, Blackbox, AIChatFree, Liaobots, Airforce]) ) gemini_flash = Model( @@ -784,11 +769,7 @@ class ModelUtils: 'gpt-4o-mini': gpt_4o_mini, 'gpt-4': gpt_4, 'gpt-4-turbo': gpt_4_turbo, - -# o1 -'o1': o1, -'o1-mini': o1_mini, - + ### Meta ### "meta-ai": meta, -- cgit v1.2.3 From 105b4aac75f26c9c216c45112ee5a8b065b5568d Mon Sep 17 00:00:00 2001 From: kqlio67 Date: Fri, 27 Sep 2024 12:13:11 +0300 Subject: New provider added ChatHub --- g4f/Provider/ChatHub.py | 84 ++++++++++++++++++++++++++++++++++++++++++ g4f/Provider/PerplexityLabs.py | 8 ++-- g4f/Provider/__init__.py | 1 + g4f/models.py | 77 ++++++++++++++++++++++++-------------- 4 files changed, 139 insertions(+), 31 deletions(-) create mode 100644 g4f/Provider/ChatHub.py (limited to 'g4f') 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/PerplexityLabs.py b/g4f/Provider/PerplexityLabs.py index ecb51f9b..b776e96a 100644 --- a/g4f/Provider/PerplexityLabs.py +++ b/g4f/Provider/PerplexityLabs.py @@ -24,10 +24,10 @@ class PerplexityLabs(AsyncGeneratorProvider, ProviderModelMixin): ] model_aliases = { - "llama-3.1-8b": "llama-3.1-sonar-large-128k-online", - "llama-3.1-8b": "sonar-small-128k-online", - "llama-3.1-8b": "llama-3.1-sonar-large-128k-chat", - "llama-3.1-8b": "llama-3.1-sonar-small-128k-chat", + "sonar-online": "llama-3.1-sonar-large-128k-online", + "sonar-online": "sonar-small-128k-online", + "sonar-chat": "llama-3.1-sonar-large-128k-chat", + "sonar-chat": "llama-3.1-sonar-small-128k-chat", "llama-3.1-8b": "llama-3.1-8b-instruct", "llama-3.1-70b": "llama-3.1-70b-instruct", } diff --git a/g4f/Provider/__init__.py b/g4f/Provider/__init__.py index d088b5ee..532b6081 100644 --- a/g4f/Provider/__init__.py +++ b/g4f/Provider/__init__.py @@ -27,6 +27,7 @@ from .Chatgpt4Online import Chatgpt4Online from .Chatgpt4o import Chatgpt4o from .ChatGptEs import ChatGptEs from .ChatgptFree import ChatgptFree +from .ChatHub import ChatHub from .DDG import DDG from .DeepInfra import DeepInfra from .DeepInfraChat import DeepInfraChat diff --git a/g4f/models.py b/g4f/models.py index bac83b5b..dcd3a525 100644 --- a/g4f/models.py +++ b/g4f/models.py @@ -16,6 +16,7 @@ from .Provider import ( Chatgpt4Online, ChatGptEs, ChatgptFree, + ChatHub, DDG, DeepInfra, DeepInfraChat, @@ -96,9 +97,7 @@ default = Model( gpt_3 = Model( name = 'gpt-3', base_provider = 'OpenAI', - best_provider = IterListProvider([ - Nexra, - ]) + best_provider = Nexra ) # gpt-3.5 @@ -167,7 +166,7 @@ meta = Model( llama_2_13b = Model( name = "llama-2-13b", base_provider = "Meta Llama", - best_provider = IterListProvider([Airforce]) + best_provider = Airforce ) # llama 3 @@ -193,7 +192,7 @@ llama_3 = Model( llama_3_1_8b = Model( name = "llama-3.1-8b", base_provider = "Meta Llama", - best_provider = IterListProvider([Blackbox, DeepInfraChat, Airforce, PerplexityLabs]) + best_provider = IterListProvider([Blackbox, DeepInfraChat, ChatHub, Airforce, PerplexityLabs]) ) llama_3_1_70b = Model( @@ -225,7 +224,7 @@ mistral_7b = Model( mixtral_8x7b = Model( name = "mixtral-8x7b", base_provider = "Mistral", - best_provider = IterListProvider([DDG, ReplicateHome, DeepInfraChat, Airforce, DeepInfra]) + best_provider = IterListProvider([DDG, ReplicateHome, DeepInfraChat, ChatHub, Airforce, DeepInfra]) ) mixtral_8x22b = Model( @@ -245,7 +244,7 @@ mistral_nemo = Model( mixtral_8x7b_dpo = Model( name = "mixtral-8x7b-dpo", base_provider = "NousResearch", - best_provider = IterListProvider([Airforce]) + best_provider = Airforce ) hermes_3 = Model( @@ -259,7 +258,7 @@ hermes_3 = Model( phi_3_medium_4k = Model( name = "phi-3-medium-4k", base_provider = "Microsoft", - best_provider = IterListProvider([DeepInfraChat]) + best_provider = DeepInfraChat ) phi_3_5_mini = Model( @@ -295,7 +294,7 @@ gemini = Model( gemma_2b_9b = Model( name = 'gemma-2b-9b', base_provider = 'Google', - best_provider = IterListProvider([Airforce]) + best_provider = Airforce ) gemma_2b_27b = Model( @@ -313,37 +312,43 @@ gemma_2b = Model( ]) ) +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( @@ -390,7 +395,7 @@ reka_core = Model( blackbox = Model( name = 'blackbox', base_provider = 'Blackbox AI', - best_provider = IterListProvider([Blackbox]) + best_provider = Blackbox ) @@ -406,7 +411,7 @@ dbrx_instruct = Model( command_r_plus = Model( name = 'command-r-plus', base_provider = 'CohereForAI', - best_provider = IterListProvider([HuggingChat]) + best_provider = HuggingChat ) @@ -422,19 +427,19 @@ sparkdesk_v1_1 = Model( 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 = IterListProvider([Airforce]) + best_provider = Airforce ) qwen_1_5_110b = Model( name = 'qwen-1.5-110b', base_provider = 'Qwen', - best_provider = IterListProvider([Airforce]) + best_provider = Airforce ) qwen_2_72b = Model( @@ -446,7 +451,7 @@ qwen_2_72b = Model( qwen_turbo = Model( name = 'qwen-turbo', base_provider = 'Qwen', - best_provider = IterListProvider([Bixin123]) + best_provider = Bixin123 ) qwen = Model( @@ -462,13 +467,13 @@ qwen = 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( @@ -484,13 +489,13 @@ glm_4 = Model( 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 = IterListProvider([Airforce]) + best_provider = Airforce ) @@ -498,7 +503,7 @@ yi_34b = Model( solar_1_mini = Model( name = 'solar-1-mini', base_provider = 'Upstage', - best_provider = IterListProvider([Upstage]) + best_provider = Upstage ) solar_10_7b = Model( @@ -525,14 +530,14 @@ pi = Model( deepseek = Model( name = 'deepseek', base_provider = 'DeepSeek', - best_provider = IterListProvider([Airforce]) + best_provider = Airforce ) ### WizardLM ### wizardlm_2_7b = Model( name = 'wizardlm-2-7b', base_provider = 'WizardLM', - best_provider = IterListProvider([DeepInfraChat]) + best_provider = DeepInfraChat ) wizardlm_2_8x22b = Model( @@ -610,6 +615,19 @@ grok_2_mini = Model( best_provider = Liaobots ) +# Perplexity +sonar_online = Model( + name = 'sonar-online', + base_provider = 'Perplexity', + best_provider = IterListProvider([ChatHub, PerplexityLabs]) +) + +sonar_chat = Model( + name = 'sonar-chat', + base_provider = 'Perplexity', + best_provider = PerplexityLabs +) + ############# @@ -817,6 +835,7 @@ class ModelUtils: 'gemma-2b': gemma_2b, 'gemma-2b-9b': gemma_2b_9b, 'gemma-2b-27b': gemma_2b_27b, +'gemma-2': gemma_2, ### Anthropic ### @@ -928,6 +947,10 @@ class ModelUtils: 'grok-2': grok_2, 'grok-2-mini': grok_2_mini, +### Perplexity ### +'sonar-online': sonar_online, +'sonar-chat': sonar_chat, + ############# -- cgit v1.2.3 From 20f2d188b91ada991462802795927c88173e7414 Mon Sep 17 00:00:00 2001 From: kqlio67 Date: Fri, 27 Sep 2024 12:26:36 +0300 Subject: New provider added GPROChat --- g4f/Provider/GPROChat.py | 76 ++++++++++++++++++++++++++++++++++++++++++++++++ g4f/Provider/__init__.py | 1 + 2 files changed, 77 insertions(+) create mode 100644 g4f/Provider/GPROChat.py (limited to 'g4f') diff --git a/g4f/Provider/GPROChat.py b/g4f/Provider/GPROChat.py new file mode 100644 index 00000000..df3a17cf --- /dev/null +++ b/g4f/Provider/GPROChat.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 GPROChat(AsyncGeneratorProvider, ProviderModelMixin): + url = "https://gprochat.com/" + 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/__init__.py b/g4f/Provider/__init__.py index 532b6081..82cb9ff2 100644 --- a/g4f/Provider/__init__.py +++ b/g4f/Provider/__init__.py @@ -39,6 +39,7 @@ from .FreeGpt import FreeGpt from .FreeNetfly import FreeNetfly from .GeminiPro import GeminiPro from .GigaChat import GigaChat +from .GPROChat import GPROChat from .HuggingChat import HuggingChat from .HuggingFace import HuggingFace from .Koala import Koala -- cgit v1.2.3 From 1d676e3fc67b5fa93f6dc8d3809d0751d36755b3 Mon Sep 17 00:00:00 2001 From: kqlio67 Date: Fri, 27 Sep 2024 13:37:47 +0300 Subject: Update g4f/models.py. Fix g4f/Provider/GPROChat.py --- g4f/Provider/GPROChat.py | 101 +++++++++++++++++++++-------------------------- g4f/models.py | 3 +- 2 files changed, 48 insertions(+), 56 deletions(-) (limited to 'g4f') diff --git a/g4f/Provider/GPROChat.py b/g4f/Provider/GPROChat.py index df3a17cf..a33c9571 100644 --- a/g4f/Provider/GPROChat.py +++ b/g4f/Provider/GPROChat.py @@ -1,76 +1,67 @@ from __future__ import annotations - +import hashlib 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 aiohttp import ClientSession from ..typing import AsyncResult, Messages from .base_provider import AsyncGeneratorProvider, ProviderModelMixin - +from .helper import format_prompt class GPROChat(AsyncGeneratorProvider, ProviderModelMixin): - url = "https://gprochat.com/" + 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, - connector: BaseConnector = None, - **kwargs, + **kwargs ) -> AsyncResult: + model = cls.get_model(model) + timestamp = int(time.time() * 1000) + prompt = format_prompt(messages) + sign = cls.generate_signature(timestamp, prompt) + 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", + "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( - 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() + 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/models.py b/g4f/models.py index dcd3a525..971313cb 100644 --- a/g4f/models.py +++ b/g4f/models.py @@ -28,6 +28,7 @@ from .Provider import ( Gemini, GeminiPro, GigaChat, + GPROChat, HuggingChat, HuggingFace, Koala, @@ -272,7 +273,7 @@ phi_3_5_mini = Model( gemini_pro = Model( name = 'gemini-pro', base_provider = 'Google DeepMind', - best_provider = IterListProvider([GeminiPro, LiteIcoding, Blackbox, AIChatFree, Liaobots, Airforce]) + best_provider = IterListProvider([GeminiPro, LiteIcoding, Blackbox, AIChatFree, GPROChat, Liaobots, Airforce]) ) gemini_flash = Model( -- cgit v1.2.3 From 4bdee965336abfaccf55a39e8a70d804b11d1662 Mon Sep 17 00:00:00 2001 From: kqlio67 Date: Fri, 27 Sep 2024 14:18:00 +0300 Subject: Updated docs/providers-and-models.md g4f/models.py --- g4f/models.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'g4f') diff --git a/g4f/models.py b/g4f/models.py index 971313cb..8a8d4e18 100644 --- a/g4f/models.py +++ b/g4f/models.py @@ -616,16 +616,16 @@ grok_2_mini = Model( best_provider = Liaobots ) -# Perplexity +# Perplexity AI sonar_online = Model( name = 'sonar-online', - base_provider = 'Perplexity', + base_provider = 'Perplexity AI', best_provider = IterListProvider([ChatHub, PerplexityLabs]) ) sonar_chat = Model( name = 'sonar-chat', - base_provider = 'Perplexity', + base_provider = 'Perplexity AI', best_provider = PerplexityLabs ) @@ -948,7 +948,7 @@ class ModelUtils: 'grok-2': grok_2, 'grok-2-mini': grok_2_mini, -### Perplexity ### +### Perplexity AI ### 'sonar-online': sonar_online, 'sonar-chat': sonar_chat, -- cgit v1.2.3 From 58db9e03f0a25613cf90cf8184ebf159123e7477 Mon Sep 17 00:00:00 2001 From: kqlio67 Date: Sun, 29 Sep 2024 23:38:25 +0300 Subject: feat(g4f/Provider/Nexra.py): enhance model handling and add new providers --- g4f/Provider/Nexra.py | 118 +++++++++++++++++----------------- g4f/Provider/nexra/NexraBing.py | 82 +++++++++++++++++++++++ g4f/Provider/nexra/NexraChatGPT.py | 66 +++++++++++++++++++ g4f/Provider/nexra/NexraChatGPT4o.py | 52 +++++++++++++++ g4f/Provider/nexra/NexraChatGPTWeb.py | 53 +++++++++++++++ g4f/Provider/nexra/NexraGeminiPro.py | 52 +++++++++++++++ g4f/Provider/nexra/NexraImageURL.py | 46 +++++++++++++ g4f/Provider/nexra/NexraLlama.py | 52 +++++++++++++++ g4f/Provider/nexra/NexraQwen.py | 52 +++++++++++++++ g4f/Provider/nexra/__init__.py | 1 + g4f/models.py | 32 ++++----- 11 files changed, 532 insertions(+), 74 deletions(-) create mode 100644 g4f/Provider/nexra/NexraBing.py create mode 100644 g4f/Provider/nexra/NexraChatGPT.py create mode 100644 g4f/Provider/nexra/NexraChatGPT4o.py create mode 100644 g4f/Provider/nexra/NexraChatGPTWeb.py create mode 100644 g4f/Provider/nexra/NexraGeminiPro.py create mode 100644 g4f/Provider/nexra/NexraImageURL.py create mode 100644 g4f/Provider/nexra/NexraLlama.py create mode 100644 g4f/Provider/nexra/NexraQwen.py create mode 100644 g4f/Provider/nexra/__init__.py (limited to 'g4f') diff --git a/g4f/Provider/Nexra.py b/g4f/Provider/Nexra.py index b2b83837..33e794f6 100644 --- a/g4f/Provider/Nexra.py +++ b/g4f/Provider/Nexra.py @@ -1,32 +1,49 @@ from __future__ import annotations -import json -from aiohttp import ClientSession -from ..typing import AsyncResult, Messages +from aiohttp import ClientSession from .base_provider import AsyncGeneratorProvider, ProviderModelMixin from .helper import format_prompt -from ..image import ImageResponse +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" - chat_api_endpoint = "https://nexra.aryahcr.cc/api/chat/gpt" - image_api_endpoint = "https://nexra.aryahcr.cc/api/image/complements" working = True supports_gpt_35_turbo = True supports_gpt_4 = True + supports_stream = True supports_system_message = True supports_message_history = True - default_model = 'gpt-3.5-turbo' - text_models = [ - 'gpt-4', 'gpt-4-0613', 'gpt-4-32k', 'gpt-4-0314', 'gpt-4-32k-0314', - 'gpt-3.5-turbo', 'gpt-3.5-turbo-16k', 'gpt-3.5-turbo-0613', 'gpt-3.5-turbo-16k-0613', 'gpt-3.5-turbo-0301', - 'gpt-3', 'text-davinci-003', 'text-davinci-002', 'code-davinci-002', - 'text-curie-001', 'text-babbage-001', 'text-ada-001', - 'davinci', 'curie', 'babbage', 'ada', 'babbage-002', 'davinci-002', - ] - image_models = ['dalle', 'dalle2', 'dalle-mini', 'emi'] - models = [*text_models, *image_models] + image_model = 'sdxl-turbo' + + 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", @@ -53,18 +70,34 @@ class Nexra(AsyncGeneratorProvider, ProviderModelMixin): "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.text_models or model in cls.image_models: + if model in cls.models: return model elif model in cls.model_aliases: return cls.model_aliases[model] else: return cls.default_model + @classmethod + def get_api_endpoint(cls, model: str) -> str: + provider_class = cls.model_to_provider.get(model) + + if provider_class: + return provider_class.api_endpoint + raise ValueError(f"API endpoint for model {model} not found.") + @classmethod async def create_async_generator( cls, @@ -74,43 +107,12 @@ class Nexra(AsyncGeneratorProvider, ProviderModelMixin): **kwargs ) -> AsyncResult: model = cls.get_model(model) - - headers = { - "Content-Type": "application/json", - } - - async with ClientSession(headers=headers) as session: - if model in cls.image_models: - # Image generation - prompt = messages[-1]['content'] if messages else "" - data = { - "prompt": prompt, - "model": model, - "response": "url" - } - async with session.post(cls.image_api_endpoint, json=data, proxy=proxy) as response: - response.raise_for_status() - result = await response.text() - result_json = json.loads(result.strip('_')) - image_url = result_json['images'][0] if result_json['images'] else None - - if image_url: - yield ImageResponse(images=image_url, alt=prompt) - else: - # Text completion - data = { - "messages": messages, - "prompt": format_prompt(messages), - "model": model, - "markdown": False - } - async with session.post(cls.chat_api_endpoint, json=data, proxy=proxy) as response: - response.raise_for_status() - result = await response.text() - - try: - json_response = json.loads(result) - gpt_response = json_response.get('gpt', '') - yield gpt_response - except json.JSONDecodeError: - yield result + api_endpoint = cls.get_api_endpoint(model) + + provider_class = cls.model_to_provider.get(model) + + 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/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/models.py b/g4f/models.py index 8a8d4e18..2940b96a 100644 --- a/g4f/models.py +++ b/g4f/models.py @@ -115,7 +115,7 @@ gpt_4o = Model( name = 'gpt-4o', base_provider = 'OpenAI', best_provider = IterListProvider([ - Liaobots, Airforce, Chatgpt4o, ChatGptEs, + Liaobots, Nexra, Airforce, Chatgpt4o, ChatGptEs, OpenaiChat ]) ) @@ -211,7 +211,7 @@ llama_3_1_405b = Model( llama_3_1 = Model( name = "llama-3.1", base_provider = "Meta Llama", - best_provider = IterListProvider([llama_3_1_8b.best_provider, llama_3_1_70b.best_provider, llama_3_1_405b.best_provider,]) + best_provider = IterListProvider([Nexra, llama_3_1_8b.best_provider, llama_3_1_70b.best_provider, llama_3_1_405b.best_provider,]) ) @@ -273,7 +273,7 @@ phi_3_5_mini = Model( gemini_pro = Model( name = 'gemini-pro', base_provider = 'Google DeepMind', - best_provider = IterListProvider([GeminiPro, LiteIcoding, Blackbox, AIChatFree, GPROChat, Liaobots, Airforce]) + best_provider = IterListProvider([GeminiPro, LiteIcoding, Blackbox, AIChatFree, GPROChat, Nexra, Liaobots, Airforce]) ) gemini_flash = Model( @@ -285,10 +285,7 @@ gemini_flash = Model( gemini = Model( name = 'gemini', base_provider = 'Google DeepMind', - best_provider = IterListProvider([ - Gemini, - gemini_flash.best_provider, gemini_pro.best_provider - ]) + best_provider = IterListProvider([Gemini, gemini_flash.best_provider, gemini_pro.best_provider]) ) # gemma @@ -458,9 +455,7 @@ qwen_turbo = Model( qwen = Model( name = 'qwen', base_provider = 'Qwen', - best_provider = IterListProvider([ - 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 - ]) + 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]) ) @@ -639,7 +634,7 @@ sonar_chat = Model( sdxl = Model( name = 'sdxl', base_provider = 'Stability AI', - best_provider = IterListProvider([ReplicateHome, DeepInfraImage]) + best_provider = IterListProvider([ReplicateHome, Nexra, DeepInfraImage]) ) @@ -734,10 +729,7 @@ dalle_3 = Model( dalle = Model( name = 'dalle', base_provider = '', - best_provider = IterListProvider([ - Nexra, - dalle_2.best_provider, dalle_3.best_provider, - ]) + best_provider = IterListProvider([Nexra, dalle_2.best_provider, dalle_3.best_provider]) ) @@ -748,7 +740,7 @@ dalle_mini = Model( ) -### ### +### Other ### emi = Model( name = 'emi', base_provider = '', @@ -763,6 +755,13 @@ any_dark = Model( ) +prodia = Model( + name = 'prodia', + base_provider = '', + best_provider = IterListProvider([Nexra]) + +) + class ModelUtils: """ Utility class for mapping string identifiers to Model instances. @@ -985,6 +984,7 @@ class ModelUtils: 'dalle-mini': dalle_mini, 'emi': emi, 'any-dark': any_dark, +'prodia': prodia, } _all_models = list(ModelUtils.convert.keys()) -- cgit v1.2.3