From eb48299195805bbcba30275a2bf857955e1287ec Mon Sep 17 00:00:00 2001 From: Heiner Lohaus Date: Fri, 8 Mar 2024 10:12:13 +0100 Subject: Enable Liaobots, disable Phind provider --- g4f/Provider/FlowGpt.py | 2 - g4f/Provider/Liaobots.py | 5 +- g4f/Provider/Phind.py | 139 ----------------------------------- g4f/Provider/__init__.py | 1 - g4f/Provider/deprecated/Phind.py | 140 ++++++++++++++++++++++++++++++++++++ g4f/Provider/deprecated/__init__.py | 3 +- g4f/errors.py | 3 + g4f/gui/client/html/index.html | 1 - 8 files changed, 149 insertions(+), 145 deletions(-) delete mode 100644 g4f/Provider/Phind.py create mode 100644 g4f/Provider/deprecated/Phind.py (limited to 'g4f') diff --git a/g4f/Provider/FlowGpt.py b/g4f/Provider/FlowGpt.py index b466a2e6..93e7955c 100644 --- a/g4f/Provider/FlowGpt.py +++ b/g4f/Provider/FlowGpt.py @@ -10,11 +10,9 @@ class FlowGpt(AsyncGeneratorProvider, ProviderModelMixin): url = "https://flowgpt.com/chat" working = True supports_gpt_35_turbo = True - supports_gpt_4 = True supports_message_history = True default_model = "gpt-3.5-turbo" models = [ - "gpt-4", "gpt-3.5-turbo", "gpt-3.5-long", "google-gemini", diff --git a/g4f/Provider/Liaobots.py b/g4f/Provider/Liaobots.py index 79e48ace..92154d7d 100644 --- a/g4f/Provider/Liaobots.py +++ b/g4f/Provider/Liaobots.py @@ -7,6 +7,7 @@ from aiohttp import ClientSession, BaseConnector from ..typing import AsyncResult, Messages from .base_provider import AsyncGeneratorProvider, ProviderModelMixin from .helper import get_connector +from ..errors import RateLimitError models = { "gpt-4": { @@ -73,7 +74,7 @@ models = { class Liaobots(AsyncGeneratorProvider, ProviderModelMixin): url = "https://liaobots.site" - working = False + working = True supports_message_history = True supports_gpt_35_turbo = True supports_gpt_4 = True @@ -122,6 +123,8 @@ class Liaobots(AsyncGeneratorProvider, ProviderModelMixin): json={"authcode": ""}, verify_ssl=False ) as response: + if response.status == 401: + raise RateLimitError("Rate limit reached. Use a other provider or ip address") response.raise_for_status() cls._auth_code = (await response.json(content_type=None))["authCode"] cls._cookie_jar = session.cookie_jar diff --git a/g4f/Provider/Phind.py b/g4f/Provider/Phind.py deleted file mode 100644 index 096cdd29..00000000 --- a/g4f/Provider/Phind.py +++ /dev/null @@ -1,139 +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 = 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/__init__.py b/g4f/Provider/__init__.py index 52ba0274..7832f871 100644 --- a/g4f/Provider/__init__.py +++ b/g4f/Provider/__init__.py @@ -51,7 +51,6 @@ from .Liaobots import Liaobots from .Llama2 import Llama2 from .OnlineGpt import OnlineGpt from .PerplexityLabs import PerplexityLabs -from .Phind import Phind from .Pi import Pi from .Vercel import Vercel from .Ylokh import Ylokh 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/__init__.py b/g4f/Provider/deprecated/__init__.py index 4d7eb5da..8ec5f2fc 100644 --- a/g4f/Provider/deprecated/__init__.py +++ b/g4f/Provider/deprecated/__init__.py @@ -22,4 +22,5 @@ from .Cromicle import Cromicle from .Opchatgpts import Opchatgpts from .Yqcloud import Yqcloud from .Aichat import Aichat -from .Berlin import Berlin \ No newline at end of file +from .Berlin import Berlin +from .Phind import Phind \ No newline at end of file diff --git a/g4f/errors.py b/g4f/errors.py index 5e821ded..00cf8cdb 100644 --- a/g4f/errors.py +++ b/g4f/errors.py @@ -35,4 +35,7 @@ class MissingAuthError(Exception): ... class NoImageResponseError(Exception): + ... + +class RateLimitError(Exception): ... \ No newline at end of file diff --git a/g4f/gui/client/html/index.html b/g4f/gui/client/html/index.html index 887562c2..86ab157d 100644 --- a/g4f/gui/client/html/index.html +++ b/g4f/gui/client/html/index.html @@ -183,7 +183,6 @@ - -- cgit v1.2.3