From f6ef3cb2237d8c336e915ef77ddbe6f37934c4fd Mon Sep 17 00:00:00 2001 From: MIDORIBIN Date: Fri, 28 Jul 2023 19:07:17 +0900 Subject: refactor: refactor provider --- g4f/Provider/AItianhu.py | 54 +++++ g4f/Provider/Acytoo.py | 47 ++++ g4f/Provider/AiService.py | 36 +++ g4f/Provider/Aichat.py | 55 +++++ g4f/Provider/Ails.py | 116 +++++++++ g4f/Provider/Bard.py | 110 +++++++++ g4f/Provider/Bing.py | 362 +++++++++++++++++++++++++++++ g4f/Provider/ChatgptAi.py | 61 +++++ g4f/Provider/ChatgptLogin.py | 133 +++++++++++ g4f/Provider/DeepAi.py | 60 +++++ g4f/Provider/DfeHub.py | 78 +++++++ g4f/Provider/EasyChat.py | 83 +++++++ g4f/Provider/Forefront.py | 41 ++++ g4f/Provider/GetGpt.py | 87 +++++++ g4f/Provider/H2o.py | 98 ++++++++ g4f/Provider/Liaobots.py | 73 ++++++ g4f/Provider/Lockchat.py | 66 ++++++ g4f/Provider/Opchatgpts.py | 62 +++++ g4f/Provider/Provider.py | 16 -- g4f/Provider/Providers/AItianhu.py | 38 --- g4f/Provider/Providers/Acytoo.py | 42 ---- g4f/Provider/Providers/AiService.py | 41 ---- g4f/Provider/Providers/Aichat.py | 45 ---- g4f/Provider/Providers/Ails.py | 95 -------- g4f/Provider/Providers/Bard.py | 76 ------ g4f/Provider/Providers/Bing.py | 352 ---------------------------- g4f/Provider/Providers/BingHuan.py | 28 --- g4f/Provider/Providers/ChatgptAi.py | 52 ----- g4f/Provider/Providers/ChatgptLogin.py | 96 -------- g4f/Provider/Providers/DeepAi.py | 74 ------ g4f/Provider/Providers/DfeHub.py | 56 ----- g4f/Provider/Providers/EasyChat.py | 59 ----- g4f/Provider/Providers/Forefront.py | 32 --- g4f/Provider/Providers/GetGpt.py | 59 ----- g4f/Provider/Providers/H2o.py | 94 -------- g4f/Provider/Providers/Liaobots.py | 53 ----- g4f/Provider/Providers/Lockchat.py | 33 --- g4f/Provider/Providers/Theb.py | 29 --- g4f/Provider/Providers/Vercel.py | 170 -------------- g4f/Provider/Providers/Wewordle.py | 73 ------ g4f/Provider/Providers/You.py | 25 -- g4f/Provider/Providers/Yqcloud.py | 38 --- g4f/Provider/Providers/__init__.py | 0 g4f/Provider/Providers/helpers/binghuan.py | 221 ------------------ g4f/Provider/Providers/helpers/theb.py | 48 ---- g4f/Provider/Providers/helpers/you.py | 79 ------- g4f/Provider/Providers/opchatgpts.py | 42 ---- g4f/Provider/Raycast.py | 56 +++++ g4f/Provider/Theb.py | 39 ++++ g4f/Provider/Vercel.py | 337 +++++++++++++++++++++++++++ g4f/Provider/Wewordle.py | 75 ++++++ g4f/Provider/You.py | 59 +++++ g4f/Provider/Yqcloud.py | 44 ++++ g4f/Provider/__init__.py | 81 ++++--- g4f/Provider/base_provider.py | 33 +++ 55 files changed, 2317 insertions(+), 2095 deletions(-) create mode 100644 g4f/Provider/AItianhu.py create mode 100644 g4f/Provider/Acytoo.py create mode 100644 g4f/Provider/AiService.py create mode 100644 g4f/Provider/Aichat.py create mode 100644 g4f/Provider/Ails.py create mode 100644 g4f/Provider/Bard.py create mode 100644 g4f/Provider/Bing.py create mode 100644 g4f/Provider/ChatgptAi.py create mode 100644 g4f/Provider/ChatgptLogin.py create mode 100644 g4f/Provider/DeepAi.py create mode 100644 g4f/Provider/DfeHub.py create mode 100644 g4f/Provider/EasyChat.py create mode 100644 g4f/Provider/Forefront.py create mode 100644 g4f/Provider/GetGpt.py create mode 100644 g4f/Provider/H2o.py create mode 100644 g4f/Provider/Liaobots.py create mode 100644 g4f/Provider/Lockchat.py create mode 100644 g4f/Provider/Opchatgpts.py delete mode 100644 g4f/Provider/Provider.py delete mode 100644 g4f/Provider/Providers/AItianhu.py delete mode 100644 g4f/Provider/Providers/Acytoo.py delete mode 100644 g4f/Provider/Providers/AiService.py delete mode 100644 g4f/Provider/Providers/Aichat.py delete mode 100644 g4f/Provider/Providers/Ails.py delete mode 100644 g4f/Provider/Providers/Bard.py delete mode 100644 g4f/Provider/Providers/Bing.py delete mode 100644 g4f/Provider/Providers/BingHuan.py delete mode 100644 g4f/Provider/Providers/ChatgptAi.py delete mode 100644 g4f/Provider/Providers/ChatgptLogin.py delete mode 100644 g4f/Provider/Providers/DeepAi.py delete mode 100644 g4f/Provider/Providers/DfeHub.py delete mode 100644 g4f/Provider/Providers/EasyChat.py delete mode 100644 g4f/Provider/Providers/Forefront.py delete mode 100644 g4f/Provider/Providers/GetGpt.py delete mode 100644 g4f/Provider/Providers/H2o.py delete mode 100644 g4f/Provider/Providers/Liaobots.py delete mode 100644 g4f/Provider/Providers/Lockchat.py delete mode 100644 g4f/Provider/Providers/Theb.py delete mode 100644 g4f/Provider/Providers/Vercel.py delete mode 100644 g4f/Provider/Providers/Wewordle.py delete mode 100644 g4f/Provider/Providers/You.py delete mode 100644 g4f/Provider/Providers/Yqcloud.py delete mode 100644 g4f/Provider/Providers/__init__.py delete mode 100644 g4f/Provider/Providers/helpers/binghuan.py delete mode 100644 g4f/Provider/Providers/helpers/theb.py delete mode 100644 g4f/Provider/Providers/helpers/you.py delete mode 100644 g4f/Provider/Providers/opchatgpts.py create mode 100644 g4f/Provider/Raycast.py create mode 100644 g4f/Provider/Theb.py create mode 100644 g4f/Provider/Vercel.py create mode 100644 g4f/Provider/Wewordle.py create mode 100644 g4f/Provider/You.py create mode 100644 g4f/Provider/Yqcloud.py create mode 100644 g4f/Provider/base_provider.py (limited to 'g4f/Provider') diff --git a/g4f/Provider/AItianhu.py b/g4f/Provider/AItianhu.py new file mode 100644 index 00000000..e8e5714a --- /dev/null +++ b/g4f/Provider/AItianhu.py @@ -0,0 +1,54 @@ +import json + +import requests + +from ..typing import Any, CreateResult +from .base_provider import BaseProvider + + +class AItianhu(BaseProvider): + url = "https://www.aitianhu.com/api/chat-process" + working = False + supports_gpt_35_turbo = True + + @staticmethod + def create_completion( + model: str, + messages: list[dict[str, str]], + stream: bool, + **kwargs: Any, + ) -> CreateResult: + base = "" + for message in messages: + base += "%s: %s\n" % (message["role"], message["content"]) + base += "assistant:" + + headers = { + "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: dict[str, Any] = { + "prompt": base, + "options": {}, + "systemMessage": "You are ChatGPT, a large language model trained by OpenAI. Follow the user's instructions carefully. Respond using markdown.", + "temperature": kwargs.get("temperature", 0.8), + "top_p": kwargs.get("top_p", 1), + } + url = "https://www.aitianhu.com/api/chat-process" + response = requests.post(url, headers=headers, json=data) + response.raise_for_status() + lines = response.text.strip().split("\n") + res = json.loads(lines[-1]) + yield res["text"] + + @classmethod + @property + def params(cls): + params = [ + ("model", "str"), + ("messages", "list[dict[str, str]]"), + ("stream", "bool"), + ("temperature", "float"), + ("top_p", "int"), + ] + param = ", ".join([": ".join(p) for p in params]) + return f"g4f.provider.{cls.__name__} supports: ({param})" diff --git a/g4f/Provider/Acytoo.py b/g4f/Provider/Acytoo.py new file mode 100644 index 00000000..32c67c0c --- /dev/null +++ b/g4f/Provider/Acytoo.py @@ -0,0 +1,47 @@ +import time + +import requests + +from ..typing import Any, CreateResult +from .base_provider import BaseProvider + + +class Acytoo(BaseProvider): + url = "https://chat.acytoo.com/api/completions" + working = True + supports_gpt_35_turbo = True + + @staticmethod + def create_completion( + model: str, + messages: list[dict[str, str]], + stream: bool, + **kwargs: Any, + ) -> CreateResult: + headers = _create_header() + payload = _create_payload(messages) + + url = "https://chat.acytoo.com/api/completions" + response = requests.post(url=url, headers=headers, json=payload) + response.raise_for_status() + yield response.text + + +def _create_header(): + return { + "accept": "*/*", + "content-type": "application/json", + } + + +def _create_payload(messages: list[dict[str, str]]): + payload_messages = [ + message | {"createdAt": int(time.time()) * 1000} for message in messages + ] + return { + "key": "", + "model": "gpt-3.5-turbo", + "messages": payload_messages, + "temperature": 1, + "password": "", + } diff --git a/g4f/Provider/AiService.py b/g4f/Provider/AiService.py new file mode 100644 index 00000000..2c0d5de2 --- /dev/null +++ b/g4f/Provider/AiService.py @@ -0,0 +1,36 @@ +import requests + +from ..typing import Any, CreateResult +from .base_provider import BaseProvider + + +class AiService(BaseProvider): + url = "https://aiservice.vercel.app/api/chat/answer" + working = False + supports_gpt_35_turbo = True + + @staticmethod + def create_completion( + model: str, + messages: list[dict[str, str]], + stream: bool, + **kwargs: Any, + ) -> CreateResult: + base = "" + for message in messages: + base += "%s: %s\n" % (message["role"], message["content"]) + base += "assistant:" + + 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/Aichat.py b/g4f/Provider/Aichat.py new file mode 100644 index 00000000..6992d071 --- /dev/null +++ b/g4f/Provider/Aichat.py @@ -0,0 +1,55 @@ +import requests + +from ..typing import Any, CreateResult +from .base_provider import BaseProvider + + +class Aichat(BaseProvider): + url = "https://chat-gpt.org/chat" + working = True + supports_gpt_35_turbo = True + + @staticmethod + def create_completion( + model: str, + messages: list[dict[str, str]], + stream: bool, + **kwargs: Any, + ) -> CreateResult: + base = "" + + for message in messages: + base += "%s: %s\n" % (message["role"], message["content"]) + base += "assistant:" + + headers = { + "authority": "chat-gpt.org", + "accept": "*/*", + "cache-control": "no-cache", + "content-type": "application/json", + "origin": "https://chat-gpt.org", + "pragma": "no-cache", + "referer": "https://chat-gpt.org/chat", + "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/113.0.0.0 Safari/537.36", + } + + json_data = { + "message": base, + "temperature": 1, + "presence_penalty": 0, + "top_p": 1, + "frequency_penalty": 0, + } + + response = requests.post( + "https://chat-gpt.org/api/text", + headers=headers, + json=json_data, + ) + response.raise_for_status() + yield response.json()["message"] diff --git a/g4f/Provider/Ails.py b/g4f/Provider/Ails.py new file mode 100644 index 00000000..52b3745d --- /dev/null +++ b/g4f/Provider/Ails.py @@ -0,0 +1,116 @@ +import hashlib +import json +import time +import uuid +from datetime import datetime + +import requests + +from ..typing import SHA256, Any, CreateResult +from .base_provider import BaseProvider + + +class Ails(BaseProvider): + url: str = "https://ai.ls" + working = True + 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": "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": _get_client_v(), + "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", + } + + timestamp = _format_timestamp(int(time.time() * 1000)) + sig = { + "d": datetime.now().strftime("%Y-%m-%d"), + "t": timestamp, + "s": _hash({"t": timestamp, "m": messages[-1]["content"]}), + } + + json_data = json.dumps( + separators=(",", ":"), + obj={ + "model": "gpt-3.5-turbo", + "temperature": kwargs.get("temperature", 0.6), + "stream": True, + "messages": messages, + } + | sig, + ) + + response = requests.post( + "https://api.caipacity.com/v1/chat/completions", + headers=headers, + data=json_data, + stream=True, + ) + response.raise_for_status() + + for token in response.iter_lines(): + if b"content" in token: + completion_chunk = json.loads(token.decode().replace("data: ", "")) + token = completion_chunk["choices"][0]["delta"].get("content") + if token != None: + yield token + + @classmethod + @property + def params(cls): + params = [ + ("model", "str"), + ("messages", "list[dict[str, str]]"), + ("stream", "bool"), + ("temperature", "float"), + ] + param = ", ".join([": ".join(p) for p in params]) + return f"g4f.provider.{cls.__name__} supports: ({param})" + + +def _hash(json_data: dict[str, str]) -> SHA256: + base_string: str = "%s:%s:%s:%s" % ( + 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) + + +def _get_client_v(): + response = requests.get("https://ai.ls/?chat=1") + response.raise_for_status() + js_path = response.text.split('crossorigin href="')[1].split('"')[0] + + response = requests.get("https://ai.ls" + js_path) + response.raise_for_status() + return response.text.split('G4="')[1].split('"')[0] diff --git a/g4f/Provider/Bard.py b/g4f/Provider/Bard.py new file mode 100644 index 00000000..cc8ea055 --- /dev/null +++ b/g4f/Provider/Bard.py @@ -0,0 +1,110 @@ +import json +import random +import re + +import browser_cookie3 +import requests + +from ..typing import Any, CreateResult +from .base_provider import BaseProvider + + +class Bard(BaseProvider): + url = "https://bard.google.com" + needs_auth = True + working = True + + @staticmethod + def create_completion( + model: str, + messages: list[dict[str, str]], + stream: bool, + **kwargs: Any, + ) -> CreateResult: + psid = { + cookie.name: cookie.value + for cookie in browser_cookie3.chrome(domain_name=".google.com") + }["__Secure-1PSID"] + + formatted = "\n".join( + ["%s: %s" % (message["role"], message["content"]) for message in messages] + ) + prompt = f"{formatted}\nAssistant:" + + proxy = kwargs.get("proxy", False) + if proxy == False: + print( + "warning!, you did not give a proxy, a lot of countries are banned from Google Bard, so it may not work" + ) + + snlm0e = None + conversation_id = None + response_id = None + choice_id = None + + client = requests.Session() + client.proxies = ( + {"http": f"http://{proxy}", "https": f"http://{proxy}"} if proxy else {} + ) + + client.headers = { + "authority": "bard.google.com", + "content-type": "application/x-www-form-urlencoded;charset=UTF-8", + "origin": "https://bard.google.com", + "referer": "https://bard.google.com/", + "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", + "x-same-domain": "1", + "cookie": f"__Secure-1PSID={psid}", + } + + if snlm0e is not None: + result = re.search( + r"SNlM0e\":\"(.*?)\"", client.get("https://bard.google.com/").text + ) + if result is not None: + snlm0e = result.group(1) + + params = { + "bl": "boq_assistant-bard-web-server_20230326.21_p0", + "_reqid": random.randint(1111, 9999), + "rt": "c", + } + + data = { + "at": snlm0e, + "f.req": json.dumps( + [ + None, + json.dumps( + [[prompt], None, [conversation_id, response_id, choice_id]] + ), + ] + ), + } + + intents = ".".join(["assistant", "lamda", "BardFrontendService"]) + + response = client.post( + f"https://bard.google.com/_/BardChatUi/data/{intents}/StreamGenerate", + data=data, + params=params, + ) + response.raise_for_status() + + chat_data = json.loads(response.content.splitlines()[3])[0][2] + if chat_data: + json_chat_data = json.loads(chat_data) + + yield json_chat_data[0][0] + + @classmethod + @property + def params(cls): + params = [ + ("model", "str"), + ("messages", "list[dict[str, str]]"), + ("stream", "bool"), + ("proxy", "str"), + ] + param = ", ".join([": ".join(p) for p in params]) + return f"g4f.provider.{cls.__name__} supports: ({param})" diff --git a/g4f/Provider/Bing.py b/g4f/Provider/Bing.py new file mode 100644 index 00000000..40e112a9 --- /dev/null +++ b/g4f/Provider/Bing.py @@ -0,0 +1,362 @@ +import asyncio +import json +import os +import random +import ssl +import uuid + +import aiohttp +import certifi +import requests + +from ..typing import Any, AsyncGenerator, CreateResult, Tuple +from .base_provider import BaseProvider + + +class Bing(BaseProvider): + url = "https://bing.com/chat" + supports_gpt_4 = True + + @staticmethod + def create_completion( + model: str, + messages: list[dict[str, str]], + stream: bool, + **kwargs: Any, + ) -> CreateResult: + if len(messages) < 2: + prompt = messages[0]["content"] + context = False + + else: + prompt = messages[-1]["content"] + context = convert(messages[:-1]) + + response = run(stream_generate(prompt, jailbreak, context)) + for token in response: + yield token + + +def convert(messages: list[dict[str, str]]): + context = "" + + for message in messages: + context += "[%s](#message)\n%s\n\n" % (message["role"], message["content"]) + + return context + + +jailbreak = { + "optionsSets": [ + "saharasugg", + "enablenewsfc", + "clgalileo", + "gencontentv3", + "nlu_direct_response_filter", + "deepleo", + "disable_emoji_spoken_text", + "responsible_ai_policy_235", + "enablemm", + "h3precise" + # "harmonyv3", + "dtappid", + "cricinfo", + "cricinfov2", + "dv3sugg", + "nojbfedge", + ] +} + + +ssl_context = ssl.create_default_context() +ssl_context.load_verify_locations(certifi.where()) + + +def _format(msg: dict[str, Any]) -> str: + return json.dumps(msg, ensure_ascii=False) + Defaults.delimiter + + +async def stream_generate( + prompt: str, + mode: dict[str, list[str]] = jailbreak, + context: bool | str = False, +): + timeout = aiohttp.ClientTimeout(total=900) + session = aiohttp.ClientSession(timeout=timeout) + + conversationId, clientId, conversationSignature = await create_conversation() + + wss = await session.ws_connect( + "wss://sydney.bing.com/sydney/ChatHub", + ssl=ssl_context, + autoping=False, + headers={ + "accept": "application/json", + "accept-language": "en-US,en;q=0.9", + "content-type": "application/json", + "sec-ch-ua": '"Not_A Brand";v="99", "Microsoft Edge";v="110", "Chromium";v="110"', + "sec-ch-ua-arch": '"x86"', + "sec-ch-ua-bitness": '"64"', + "sec-ch-ua-full-version": '"109.0.1518.78"', + "sec-ch-ua-full-version-list": '"Chromium";v="110.0.5481.192", "Not A(Brand";v="24.0.0.0", "Microsoft Edge";v="110.0.1587.69"', + "sec-ch-ua-mobile": "?0", + "sec-ch-ua-model": "", + "sec-ch-ua-platform": '"Windows"', + "sec-ch-ua-platform-version": '"15.0.0"', + "sec-fetch-dest": "empty", + "sec-fetch-mode": "cors", + "sec-fetch-site": "same-origin", + "x-ms-client-request-id": str(uuid.uuid4()), + "x-ms-useragent": "azsdk-js-api-client-factory/1.0.0-beta.1 core-rest-pipeline/1.10.0 OS/Win32", + "Referer": "https://www.bing.com/search?q=Bing+AI&showconv=1&FORM=hpcodx", + "Referrer-Policy": "origin-when-cross-origin", + "x-forwarded-for": Defaults.ip_address, + }, + ) + + await wss.send_str(_format({"protocol": "json", "version": 1})) + await wss.receive(timeout=900) + + argument: dict[str, Any] = { + **mode, + "source": "cib", + "allowedMessageTypes": Defaults.allowedMessageTypes, + "sliceIds": Defaults.sliceIds, + "traceId": os.urandom(16).hex(), + "isStartOfSession": True, + "message": Defaults.location + | { + "author": "user", + "inputMethod": "Keyboard", + "text": prompt, + "messageType": "Chat", + }, + "conversationSignature": conversationSignature, + "participant": {"id": clientId}, + "conversationId": conversationId, + } + + if context: + argument["previousMessages"] = [ + { + "author": "user", + "description": context, + "contextType": "WebPage", + "messageType": "Context", + "messageId": "discover-web--page-ping-mriduna-----", + } + ] + + struct: dict[str, list[dict[str, Any]] | str | int] = { + "arguments": [argument], + "invocationId": "0", + "target": "chat", + "type": 4, + } + + await wss.send_str(_format(struct)) + + final = False + draw = False + resp_txt = "" + result_text = "" + resp_txt_no_link = "" + cache_text = "" + + while not final: + msg = await wss.receive(timeout=900) + objects = msg.data.split(Defaults.delimiter) # type: ignore + + for obj in objects: # type: ignore + if obj is None or not obj: + continue + + response = json.loads(obj) # type: ignore + if response.get("type") == 1 and response["arguments"][0].get( + "messages", + ): + if not draw: + if ( + response["arguments"][0]["messages"][0]["contentOrigin"] + != "Apology" + ) and not draw: + resp_txt = result_text + response["arguments"][0]["messages"][ + 0 + ]["adaptiveCards"][0]["body"][0].get("text", "") + resp_txt_no_link = result_text + response["arguments"][0][ + "messages" + ][0].get("text", "") + + if response["arguments"][0]["messages"][0].get( + "messageType", + ): + resp_txt = ( + resp_txt + + response["arguments"][0]["messages"][0][ + "adaptiveCards" + ][0]["body"][0]["inlines"][0].get("text") + + "\n" + ) + result_text = ( + result_text + + response["arguments"][0]["messages"][0][ + "adaptiveCards" + ][0]["body"][0]["inlines"][0].get("text") + + "\n" + ) + + if cache_text.endswith(" "): + final = True + if wss and not wss.closed: + await wss.close() + if session and not session.closed: + await session.close() + + yield (resp_txt.replace(cache_text, "")) + cache_text = resp_txt + + elif response.get("type") == 2: + if response["item"]["result"].get("error"): + if wss and not wss.closed: + await wss.close() + if session and not session.closed: + await session.close() + + raise Exception( + f"{response['item']['result']['value']}: {response['item']['result']['message']}" + ) + + if draw: + cache = response["item"]["messages"][1]["adaptiveCards"][0]["body"][ + 0 + ]["text"] + response["item"]["messages"][1]["adaptiveCards"][0]["body"][0][ + "text" + ] = (cache + resp_txt) + + if ( + response["item"]["messages"][-1]["contentOrigin"] == "Apology" + and resp_txt + ): + response["item"]["messages"][-1]["text"] = resp_txt_no_link + response["item"]["messages"][-1]["adaptiveCards"][0]["body"][0][ + "text" + ] = resp_txt + + # print('Preserved the message from being deleted', file=sys.stderr) + + final = True + if wss and not wss.closed: + await wss.close() + if session and not session.closed: + await session.close() + + +async def create_conversation() -> Tuple[str, str, str]: + create = requests.get( + "https://www.bing.com/turing/conversation/create", + headers={ + "authority": "edgeservices.bing.com", + "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", + "accept-language": "en-US,en;q=0.9", + "cache-control": "max-age=0", + "sec-ch-ua": '"Chromium";v="110", "Not A(Brand";v="24", "Microsoft Edge";v="110"', + "sec-ch-ua-arch": '"x86"', + "sec-ch-ua-bitness": '"64"', + "sec-ch-ua-full-version": '"110.0.1587.69"', + "sec-ch-ua-full-version-list": '"Chromium";v="110.0.5481.192", "Not A(Brand";v="24.0.0.0", "Microsoft Edge";v="110.0.1587.69"', + "sec-ch-ua-mobile": "?0", + "sec-ch-ua-model": '""', + "sec-ch-ua-platform": '"Windows"', + "sec-ch-ua-platform-version": '"15.0.0"', + "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/110.0.0.0 Safari/537.36 Edg/110.0.1587.69", + "x-edge-shopping-flag": "1", + "x-forwarded-for": Defaults.ip_address, + }, + ) + + conversationId = create.json().get("conversationId") + clientId = create.json().get("clientId") + conversationSignature = create.json().get("conversationSignature") + + if not conversationId or not clientId or not conversationSignature: + raise Exception("Failed to create conversation.") + + return conversationId, clientId, conversationSignature + + +class Defaults: + delimiter = "\x1e" + ip_address = f"13.{random.randint(104, 107)}.{random.randint(0, 255)}.{random.randint(0, 255)}" + + allowedMessageTypes = [ + "Chat", + "Disengaged", + "AdsQuery", + "SemanticSerp", + "GenerateContentQuery", + "SearchQuery", + "ActionRequest", + "Context", + "Progress", + "AdsQuery", + "SemanticSerp", + ] + + sliceIds = [ + # "222dtappid", + # "225cricinfo", + # "224locals0" + "winmuid3tf", + "osbsdusgreccf", + "ttstmout", + "crchatrev", + "winlongmsgtf", + "ctrlworkpay", + "norespwtf", + "tempcacheread", + "temptacache", + "505scss0", + "508jbcars0", + "515enbotdets0", + "5082tsports", + "515vaoprvs", + "424dagslnv1s0", + "kcimgattcf", + "427startpms0", + ] + + location = { + "locale": "en-US", + "market": "en-US", + "region": "US", + "locationHints": [ + { + "country": "United States", + "state": "California", + "city": "Los Angeles", + "timezoneoffset": 8, + "countryConfidence": 8, + "Center": {"Latitude": 34.0536909, "Longitude": -118.242766}, + "RegionType": 2, + "SourceType": 1, + } + ], + } + + +def run(generator: AsyncGenerator[Any | str, Any]): + loop = asyncio.get_event_loop() + gen = generator.__aiter__() + + while True: + try: + yield loop.run_until_complete(gen.__anext__()) + + except StopAsyncIteration: + break diff --git a/g4f/Provider/ChatgptAi.py b/g4f/Provider/ChatgptAi.py new file mode 100644 index 00000000..53518f65 --- /dev/null +++ b/g4f/Provider/ChatgptAi.py @@ -0,0 +1,61 @@ +import re + +import requests + +from ..typing import Any, CreateResult +from .base_provider import BaseProvider + + +class ChatgptAi(BaseProvider): + url = "https://chatgpt.ai/gpt-4/" + working = True + supports_gpt_4 = True + + @staticmethod + def create_completion( + model: str, + messages: list[dict[str, str]], + stream: bool, + **kwargs: Any, + ) -> CreateResult: + chat = "" + for message in messages: + chat += "%s: %s\n" % (message["role"], message["content"]) + chat += "assistant: " + + response = requests.get("https://chatgpt.ai/") + nonce, post_id, _, bot_id = re.findall( + r'data-nonce="(.*)"\n data-post-id="(.*)"\n data-url="(.*)"\n data-bot-id="(.*)"\n data-width', + response.text, + )[0] + + headers = { + "authority": "chatgpt.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", + "origin": "https://chatgpt.ai", + "pragma": "no-cache", + "referer": "https://chatgpt.ai/gpt-4/", + "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-origin", + "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 = { + "_wpnonce": nonce, + "post_id": post_id, + "url": "https://chatgpt.ai/gpt-4", + "action": "wpaicg_chat_shortcode_message", + "message": chat, + "bot_id": bot_id, + } + + response = requests.post( + "https://chatgpt.ai/wp-admin/admin-ajax.php", headers=headers, data=data + ) + response.raise_for_status() + yield response.json()["data"] diff --git a/g4f/Provider/ChatgptLogin.py b/g4f/Provider/ChatgptLogin.py new file mode 100644 index 00000000..05bd1262 --- /dev/null +++ b/g4f/Provider/ChatgptLogin.py @@ -0,0 +1,133 @@ +import base64 +import os +import re + +import requests + +from ..typing import Any, CreateResult +from .base_provider import BaseProvider + + +class ChatgptLogin(BaseProvider): + url = "https://chatgptlogin.ac" + supports_gpt_35_turbo = True + + @staticmethod + def create_completion( + model: str, + messages: list[dict[str, str]], + stream: bool, + **kwargs: Any, + ) -> CreateResult: + headers = { + "authority": "chatgptlogin.ac", + "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://chatgptlogin.ac", + "referer": "https://chatgptlogin.ac/use-chatgpt-free/", + "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-origin", + "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", + "x-wp-nonce": _get_nonce(), + } + + conversation = _transform(messages) + + json_data = { + "env": "chatbot", + "session": "N/A", + "prompt": "Converse as if you were an AI assistant. Be friendly, creative.", + "context": "Converse as if you were an AI assistant. Be friendly, creative.", + "messages": conversation, + "newMessage": messages[-1]["content"], + "userName": '
User:
', + "aiName": '
AI:
', + "model": "gpt-3.5-turbo", + "temperature": kwargs.get("temperature", 0.8), + "maxTokens": 1024, + "maxResults": 1, + "apiKey": "", + "service": "openai", + "embeddingsIndex": "", + "stop": "", + "clientId": os.urandom(6).hex(), + } + + response = requests.post( + "https://chatgptlogin.ac/wp-json/ai-chatbot/v1/chat", + headers=headers, + json=json_data, + ) + response.raise_for_status() + yield response.json()["reply"] + + @classmethod + @property + def params(cls): + params = [ + ("model", "str"), + ("messages", "list[dict[str, str]]"), + ("stream", "bool"), + ("temperature", "float"), + ] + param = ", ".join([": ".join(p) for p in params]) + return f"g4f.provider.{cls.__name__} supports: ({param})" + + +def _get_nonce() -> str: + res = requests.get( + "https://chatgptlogin.ac/use-chatgpt-free/", + headers={ + "Referer": "https://chatgptlogin.ac/use-chatgpt-free/", + "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", + }, + ) + + result = re.search( + r'class="mwai-chat mwai-chatgpt">.*Send