diff options
Diffstat (limited to 'g4f/Provider')
32 files changed, 157 insertions, 163 deletions
diff --git a/g4f/Provider/AItianhuSpace.py b/g4f/Provider/AItianhuSpace.py index 8d9feb2b..11725db7 100644 --- a/g4f/Provider/AItianhuSpace.py +++ b/g4f/Provider/AItianhuSpace.py @@ -4,12 +4,12 @@ import time import random from ..typing import CreateResult, Messages -from .base_provider import BaseProvider +from .base_provider import AbstractProvider from .helper import format_prompt, get_random_string from ..webdriver import WebDriver, WebDriverSession from .. import debug -class AItianhuSpace(BaseProvider): +class AItianhuSpace(AbstractProvider): url = "https://chat3.aiyunos.top/" working = True supports_stream = True diff --git a/g4f/Provider/DeepInfra.py b/g4f/Provider/DeepInfra.py index 754439c1..96e3a680 100644 --- a/g4f/Provider/DeepInfra.py +++ b/g4f/Provider/DeepInfra.py @@ -1,28 +1,34 @@ from __future__ import annotations -import requests, json -from ..typing import CreateResult, Messages -from .base_provider import BaseProvider +import json +from ..typing import AsyncResult, Messages +from .base_provider import AsyncGeneratorProvider +from ..requests import StreamSession -class DeepInfra(BaseProvider): - url: str = "https://deepinfra.com" - working: bool = True - supports_stream: bool = True - supports_message_history: bool = True +class DeepInfra(AsyncGeneratorProvider): + url = "https://deepinfra.com" + working = True + supports_stream = True + supports_message_history = True @staticmethod - def create_completion(model: str, - messages: Messages, - stream: bool, - **kwargs) -> CreateResult: - + async def create_async_generator( + model: str, + messages: Messages, + stream: bool, + proxy: str = None, + timeout: int = 120, + auth: str = None, + **kwargs + ) -> AsyncResult: + if not model: + model = 'meta-llama/Llama-2-70b-chat-hf' headers = { - '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', + 'Accept-Encoding': 'gzip, deflate, br', + 'Accept-Language': 'en-US', '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', @@ -34,29 +40,34 @@ class DeepInfra(BaseProvider): 'sec-ch-ua-mobile': '?0', 'sec-ch-ua-platform': '"macOS"', } - - json_data = json.dumps({ - 'model' : 'meta-llama/Llama-2-70b-chat-hf', - 'messages': messages, - 'stream' : True}, separators=(',', ':')) - - response = requests.post('https://api.deepinfra.com/v1/openai/chat/completions', - headers=headers, data=json_data, stream=True) - - response.raise_for_status() - first = True - - for line in response.iter_content(chunk_size=1024): - if line.startswith(b"data: [DONE]"): - break + if auth: + headers['Authorization'] = f"bearer {auth}" - elif line.startswith(b"data: "): - chunk = json.loads(line[6:])["choices"][0]["delta"].get("content") - - if chunk: - if first: - chunk = chunk.lstrip() + async with StreamSession(headers=headers, + timeout=timeout, + proxies={"https": proxy}, + impersonate="chrome110" + ) as session: + json_data = { + 'model' : model, + 'messages': messages, + 'stream' : True + } + async with session.post('https://api.deepinfra.com/v1/openai/chat/completions', + json=json_data) as response: + response.raise_for_status() + first = True + async for line in response.iter_lines(): + try: + if line.startswith(b"data: [DONE]"): + break + elif line.startswith(b"data: "): + chunk = json.loads(line[6:])["choices"][0]["delta"].get("content") if chunk: - first = False - - yield (chunk)
\ No newline at end of file + if first: + chunk = chunk.lstrip() + if chunk: + first = False + yield chunk + except Exception: + raise RuntimeError(f"Response: {line}")
\ No newline at end of file diff --git a/g4f/Provider/GeekGpt.py b/g4f/Provider/GeekGpt.py index 9ed9c09b..f53ec9de 100644 --- a/g4f/Provider/GeekGpt.py +++ b/g4f/Provider/GeekGpt.py @@ -1,12 +1,12 @@ from __future__ import annotations import requests, json -from .base_provider import BaseProvider +from .base_provider import AbstractProvider from ..typing import CreateResult, Messages from json import dumps -class GeekGpt(BaseProvider): +class GeekGpt(AbstractProvider): url = 'https://chat.geekgpt.org' working = True supports_message_history = True diff --git a/g4f/Provider/MyShell.py b/g4f/Provider/MyShell.py index b0a01016..145cc0bf 100644 --- a/g4f/Provider/MyShell.py +++ b/g4f/Provider/MyShell.py @@ -3,11 +3,11 @@ from __future__ import annotations import time, json from ..typing import CreateResult, Messages -from .base_provider import BaseProvider +from .base_provider import AbstractProvider from .helper import format_prompt from ..webdriver import WebDriver, WebDriverSession, bypass_cloudflare -class MyShell(BaseProvider): +class MyShell(AbstractProvider): url = "https://app.myshell.ai/chat" working = True supports_gpt_35_turbo = True diff --git a/g4f/Provider/PerplexityAi.py b/g4f/Provider/PerplexityAi.py index ad629aa8..023968dc 100644 --- a/g4f/Provider/PerplexityAi.py +++ b/g4f/Provider/PerplexityAi.py @@ -7,11 +7,11 @@ from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.keys import Keys from ..typing import CreateResult, Messages -from .base_provider import BaseProvider +from .base_provider import AbstractProvider from .helper import format_prompt from ..webdriver import WebDriver, WebDriverSession -class PerplexityAi(BaseProvider): +class PerplexityAi(AbstractProvider): url = "https://www.perplexity.ai" working = True supports_gpt_35_turbo = True diff --git a/g4f/Provider/Pi.py b/g4f/Provider/Pi.py index 529a4a52..2f7dc436 100644 --- a/g4f/Provider/Pi.py +++ b/g4f/Provider/Pi.py @@ -1,12 +1,12 @@ from __future__ import annotations -from ..typing import CreateResult, Messages -from .base_provider import BaseProvider, format_prompt - import json + +from ..typing import CreateResult, Messages +from .base_provider import AbstractProvider, format_prompt from ..requests import Session, get_session_from_browser -class Pi(BaseProvider): +class Pi(AbstractProvider): url = "https://pi.ai/talk" working = True supports_stream = True diff --git a/g4f/Provider/TalkAi.py b/g4f/Provider/TalkAi.py index 85f56dda..d4efd269 100644 --- a/g4f/Provider/TalkAi.py +++ b/g4f/Provider/TalkAi.py @@ -3,10 +3,10 @@ from __future__ import annotations import time, json, time from ..typing import CreateResult, Messages -from .base_provider import BaseProvider +from .base_provider import AbstractProvider from ..webdriver import WebDriver, WebDriverSession -class TalkAi(BaseProvider): +class TalkAi(AbstractProvider): url = "https://talkai.info" working = True supports_gpt_35_turbo = True diff --git a/g4f/Provider/Vercel.py b/g4f/Provider/Vercel.py index 3e210925..466ea3de 100644 --- a/g4f/Provider/Vercel.py +++ b/g4f/Provider/Vercel.py @@ -3,10 +3,10 @@ from __future__ import annotations import json, base64, requests, execjs, random, uuid from ..typing import Messages, TypedDict, CreateResult, Any -from .base_provider import BaseProvider +from .base_provider import AbstractProvider from ..debug import logging -class Vercel(BaseProvider): +class Vercel(AbstractProvider): url = 'https://sdk.vercel.ai' working = False supports_message_history = True diff --git a/g4f/Provider/__init__.py b/g4f/Provider/__init__.py index 4670d331..2ff8b837 100644 --- a/g4f/Provider/__init__.py +++ b/g4f/Provider/__init__.py @@ -1,11 +1,13 @@ from __future__ import annotations -from .base_provider import BaseProvider, AsyncProvider, AsyncGeneratorProvider -from .retry_provider import RetryProvider -from .deprecated import * -from .needs_auth import * -from .unfinished import * -from .selenium import * +from ..base_provider import BaseProvider, ProviderType +from .retry_provider import RetryProvider +from .base_provider import AsyncProvider, AsyncGeneratorProvider +from .deprecated import * +from .needs_auth import * +from .unfinished import * +from .selenium import * + from .Aura import Aura from .AiAsk import AiAsk from .Aichat import Aichat @@ -59,7 +61,7 @@ __modules__: list = [ getattr(sys.modules[__name__], provider) for provider in dir() if not provider.startswith("__") ] -__providers__: list[type[BaseProvider]] = [ +__providers__: list[ProviderType] = [ provider for provider in __modules__ if isinstance(provider, type) and issubclass(provider, BaseProvider) @@ -67,9 +69,9 @@ __providers__: list[type[BaseProvider]] = [ __all__: list[str] = [ provider.__name__ for provider in __providers__ ] -__map__: dict[str, type[BaseProvider]] = dict([ +__map__: dict[str, ProviderType] = dict([ (provider.__name__, provider) for provider in __providers__ ]) class ProviderUtils: - convert: dict[str, type[BaseProvider]] = __map__
\ No newline at end of file + convert: dict[str, ProviderType] = __map__
\ No newline at end of file diff --git a/g4f/Provider/base_provider.py b/g4f/Provider/base_provider.py index 62029f5d..6da7f6c6 100644 --- a/g4f/Provider/base_provider.py +++ b/g4f/Provider/base_provider.py @@ -1,12 +1,14 @@ from __future__ import annotations import sys +import asyncio from asyncio import AbstractEventLoop from concurrent.futures import ThreadPoolExecutor -from abc import ABC, abstractmethod +from abc import abstractmethod from inspect import signature, Parameter from .helper import get_event_loop, get_cookies, format_prompt -from ..typing import CreateResult, AsyncResult, Messages +from ..typing import CreateResult, AsyncResult, Messages, Union +from ..base_provider import BaseProvider if sys.version_info < (3, 10): NoneType = type(None) @@ -20,25 +22,7 @@ if sys.platform == 'win32': ): asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy()) -class BaseProvider(ABC): - url: str - working: bool = False - needs_auth: bool = False - supports_stream: bool = False - supports_gpt_35_turbo: bool = False - supports_gpt_4: bool = False - supports_message_history: bool = False - - @staticmethod - @abstractmethod - def create_completion( - model: str, - messages: Messages, - stream: bool, - **kwargs - ) -> CreateResult: - raise NotImplementedError() - +class AbstractProvider(BaseProvider): @classmethod async def create_async( cls, @@ -60,9 +44,12 @@ class BaseProvider(ABC): **kwargs )) - return await loop.run_in_executor( - executor, - create_func + return await asyncio.wait_for( + loop.run_in_executor( + executor, + create_func + ), + timeout=kwargs.get("timeout", 0) ) @classmethod @@ -102,16 +89,19 @@ class BaseProvider(ABC): return f"g4f.Provider.{cls.__name__} supports: ({args}\n)" -class AsyncProvider(BaseProvider): +class AsyncProvider(AbstractProvider): @classmethod def create_completion( cls, model: str, messages: Messages, stream: bool = False, + *, + loop: AbstractEventLoop = None, **kwargs ) -> CreateResult: - loop = get_event_loop() + if not loop: + loop = get_event_loop() coro = cls.create_async(model, messages, **kwargs) yield loop.run_until_complete(coro) @@ -134,9 +124,12 @@ class AsyncGeneratorProvider(AsyncProvider): model: str, messages: Messages, stream: bool = True, + *, + loop: AbstractEventLoop = None, **kwargs ) -> CreateResult: - loop = get_event_loop() + if not loop: + loop = get_event_loop() generator = cls.create_async_generator( model, messages, @@ -171,6 +164,7 @@ class AsyncGeneratorProvider(AsyncProvider): def create_async_generator( model: str, messages: Messages, + stream: bool = True, **kwargs ) -> AsyncResult: raise NotImplementedError() diff --git a/g4f/Provider/deprecated/AiService.py b/g4f/Provider/deprecated/AiService.py index 325af670..acd7f5ea 100644 --- a/g4f/Provider/deprecated/AiService.py +++ b/g4f/Provider/deprecated/AiService.py @@ -3,10 +3,10 @@ from __future__ import annotations import requests from ...typing import Any, CreateResult, Messages -from ..base_provider import BaseProvider +from ..base_provider import AbstractProvider -class AiService(BaseProvider): +class AiService(AbstractProvider): url = "https://aiservice.vercel.app/" working = False supports_gpt_35_turbo = True diff --git a/g4f/Provider/deprecated/Aivvm.py b/g4f/Provider/deprecated/Aivvm.py index 8b5a9e05..c973adf8 100644 --- a/g4f/Provider/deprecated/Aivvm.py +++ b/g4f/Provider/deprecated/Aivvm.py @@ -1,9 +1,10 @@ from __future__ import annotations + import requests +import json -from ..base_provider import BaseProvider +from ..base_provider import AbstractProvider from ...typing import CreateResult, Messages -from json import dumps # to recreate this easily, send a post request to https://chat.aivvm.com/api/models models = { @@ -17,7 +18,7 @@ models = { 'gpt-4-32k-0613': {'id': 'gpt-4-32k-0613', 'name': 'GPT-4-32K-0613'}, } -class Aivvm(BaseProvider): +class Aivvm(AbstractProvider): url = 'https://chat.aivvm.com' supports_stream = True working = False @@ -44,7 +45,7 @@ class Aivvm(BaseProvider): "temperature" : kwargs.get("temperature", 0.7) } - data = dumps(json_data) + data = json.dumps(json_data) headers = { "accept" : "text/event-stream", diff --git a/g4f/Provider/deprecated/DfeHub.py b/g4f/Provider/deprecated/DfeHub.py index 4458bac6..e6d13444 100644 --- a/g4f/Provider/deprecated/DfeHub.py +++ b/g4f/Provider/deprecated/DfeHub.py @@ -7,10 +7,10 @@ import time import requests from ...typing import Any, CreateResult -from ..base_provider import BaseProvider +from ..base_provider import AbstractProvider -class DfeHub(BaseProvider): +class DfeHub(AbstractProvider): url = "https://chat.dfehub.com/" supports_stream = True supports_gpt_35_turbo = True diff --git a/g4f/Provider/deprecated/EasyChat.py b/g4f/Provider/deprecated/EasyChat.py index 3142f243..7a00f523 100644 --- a/g4f/Provider/deprecated/EasyChat.py +++ b/g4f/Provider/deprecated/EasyChat.py @@ -2,14 +2,13 @@ from __future__ import annotations import json import random - import requests from ...typing import Any, CreateResult -from ..base_provider import BaseProvider +from ..base_provider import AbstractProvider -class EasyChat(BaseProvider): +class EasyChat(AbstractProvider): url: str = "https://free.easychat.work" supports_stream = True supports_gpt_35_turbo = True diff --git a/g4f/Provider/deprecated/Equing.py b/g4f/Provider/deprecated/Equing.py index 9f510e50..5fd9797b 100644 --- a/g4f/Provider/deprecated/Equing.py +++ b/g4f/Provider/deprecated/Equing.py @@ -6,10 +6,10 @@ from abc import ABC, abstractmethod import requests from ...typing import Any, CreateResult -from ..base_provider import BaseProvider +from ..base_provider import AbstractProvider -class Equing(BaseProvider): +class Equing(AbstractProvider): url: str = 'https://next.eqing.tech/' working = False supports_stream = True diff --git a/g4f/Provider/deprecated/FastGpt.py b/g4f/Provider/deprecated/FastGpt.py index 3af8c213..6a79d9aa 100644 --- a/g4f/Provider/deprecated/FastGpt.py +++ b/g4f/Provider/deprecated/FastGpt.py @@ -2,15 +2,13 @@ from __future__ import annotations import json import random -from abc import ABC, abstractmethod - import requests from ...typing import Any, CreateResult -from ..base_provider import BaseProvider +from ..base_provider import AbstractProvider -class FastGpt(BaseProvider): +class FastGpt(AbstractProvider): url: str = 'https://chat9.fastgpt.me/' working = False needs_auth = False @@ -19,7 +17,6 @@ class FastGpt(BaseProvider): supports_gpt_4 = False @staticmethod - @abstractmethod def create_completion( model: str, messages: list[dict[str, str]], diff --git a/g4f/Provider/deprecated/Forefront.py b/g4f/Provider/deprecated/Forefront.py index 2f807e91..39654b2c 100644 --- a/g4f/Provider/deprecated/Forefront.py +++ b/g4f/Provider/deprecated/Forefront.py @@ -5,10 +5,10 @@ import json import requests from ...typing import Any, CreateResult -from ..base_provider import BaseProvider +from ..base_provider import AbstractProvider -class Forefront(BaseProvider): +class Forefront(AbstractProvider): url = "https://forefront.com" supports_stream = True supports_gpt_35_turbo = True diff --git a/g4f/Provider/deprecated/GetGpt.py b/g4f/Provider/deprecated/GetGpt.py index a7f4695c..69851ee5 100644 --- a/g4f/Provider/deprecated/GetGpt.py +++ b/g4f/Provider/deprecated/GetGpt.py @@ -11,10 +11,10 @@ except ImportError: from Cryptodome.Cipher import AES from ...typing import Any, CreateResult -from ..base_provider import BaseProvider +from ..base_provider import AbstractProvider -class GetGpt(BaseProvider): +class GetGpt(AbstractProvider): url = 'https://chat.getgpt.world/' supports_stream = True working = False diff --git a/g4f/Provider/deprecated/Lockchat.py b/g4f/Provider/deprecated/Lockchat.py index f885672d..edab0bd4 100644 --- a/g4f/Provider/deprecated/Lockchat.py +++ b/g4f/Provider/deprecated/Lockchat.py @@ -5,10 +5,10 @@ import json import requests from ...typing import Any, CreateResult -from ..base_provider import BaseProvider +from ..base_provider import AbstractProvider -class Lockchat(BaseProvider): +class Lockchat(AbstractProvider): url: str = "http://supertest.lockchat.app" supports_stream = True supports_gpt_35_turbo = True diff --git a/g4f/Provider/deprecated/V50.py b/g4f/Provider/deprecated/V50.py index e24ac2d4..456445f7 100644 --- a/g4f/Provider/deprecated/V50.py +++ b/g4f/Provider/deprecated/V50.py @@ -5,10 +5,10 @@ import uuid import requests from ...typing import Any, CreateResult -from ..base_provider import BaseProvider +from ..base_provider import AbstractProvider -class V50(BaseProvider): +class V50(AbstractProvider): url = 'https://p5.v50.ltd' supports_gpt_35_turbo = True supports_stream = False diff --git a/g4f/Provider/deprecated/VoiGpt.py b/g4f/Provider/deprecated/VoiGpt.py index b312709f..9b061e63 100644 --- a/g4f/Provider/deprecated/VoiGpt.py +++ b/g4f/Provider/deprecated/VoiGpt.py @@ -2,13 +2,11 @@ from __future__ import annotations import json import requests -from .base_provider import BaseProvider -from ..typing import Messages, CreateResult -from .helper import get_cookies +from ..base_provider import AbstractProvider +from ...typing import Messages, CreateResult - -class VoiGpt(BaseProvider): +class VoiGpt(AbstractProvider): """ VoiGpt - A provider for VoiGpt.com diff --git a/g4f/Provider/deprecated/Wuguokai.py b/g4f/Provider/deprecated/Wuguokai.py index 87877198..f12d1bfe 100644 --- a/g4f/Provider/deprecated/Wuguokai.py +++ b/g4f/Provider/deprecated/Wuguokai.py @@ -5,10 +5,10 @@ import random import requests from ...typing import Any, CreateResult -from ..base_provider import BaseProvider, format_prompt +from ..base_provider import AbstractProvider, format_prompt -class Wuguokai(BaseProvider): +class Wuguokai(AbstractProvider): url = 'https://chat.wuguokai.xyz' supports_gpt_35_turbo = True working = False diff --git a/g4f/Provider/helper.py b/g4f/Provider/helper.py index ded59ee2..81f417dd 100644 --- a/g4f/Provider/helper.py +++ b/g4f/Provider/helper.py @@ -1,6 +1,5 @@ from __future__ import annotations -import sys import asyncio import webbrowser import random @@ -8,7 +7,7 @@ import string import secrets import os from os import path -from asyncio import AbstractEventLoop +from asyncio import AbstractEventLoop, BaseEventLoop from platformdirs import user_config_dir from browser_cookie3 import ( chrome, @@ -34,7 +33,8 @@ _cookies: Dict[str, Dict[str, str]] = {} def get_event_loop() -> AbstractEventLoop: try: loop = asyncio.get_event_loop() - loop._check_closed() + if isinstance(loop, BaseEventLoop): + loop._check_closed() except RuntimeError: loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) diff --git a/g4f/Provider/needs_auth/Bard.py b/g4f/Provider/needs_auth/Bard.py index 48e535dd..cf1000c4 100644 --- a/g4f/Provider/needs_auth/Bard.py +++ b/g4f/Provider/needs_auth/Bard.py @@ -8,11 +8,11 @@ from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.keys import Keys from ...typing import CreateResult, Messages -from ..base_provider import BaseProvider +from ..base_provider import AbstractProvider from ..helper import format_prompt from ...webdriver import WebDriver, WebDriverSession -class Bard(BaseProvider): +class Bard(AbstractProvider): url = "https://bard.google.com" working = True needs_auth = True diff --git a/g4f/Provider/needs_auth/HuggingChat.py b/g4f/Provider/needs_auth/HuggingChat.py index 41c938b4..e4fa237d 100644 --- a/g4f/Provider/needs_auth/HuggingChat.py +++ b/g4f/Provider/needs_auth/HuggingChat.py @@ -8,6 +8,9 @@ from ...typing import AsyncResult, Messages from ..base_provider import AsyncGeneratorProvider from ..helper import format_prompt, get_cookies +map = { + "openchat/openchat_3.5": "openchat/openchat-3.5-1210", +} class HuggingChat(AsyncGeneratorProvider): url = "https://huggingface.co/chat" @@ -25,7 +28,10 @@ class HuggingChat(AsyncGeneratorProvider): cookies: dict = None, **kwargs ) -> AsyncResult: - model = model if model else cls.model + if not model: + model = cls.model + elif model in map: + model = map[model] if not cookies: cookies = get_cookies(".huggingface.co") diff --git a/g4f/Provider/needs_auth/Poe.py b/g4f/Provider/needs_auth/Poe.py index 200ded3b..41c5315a 100644 --- a/g4f/Provider/needs_auth/Poe.py +++ b/g4f/Provider/needs_auth/Poe.py @@ -3,7 +3,7 @@ from __future__ import annotations import time from ...typing import CreateResult, Messages -from ..base_provider import BaseProvider +from ..base_provider import AbstractProvider from ..helper import format_prompt from ...webdriver import WebDriver, WebDriverSession @@ -20,7 +20,7 @@ models = { "palm": {"name": "Google-PaLM"}, } -class Poe(BaseProvider): +class Poe(AbstractProvider): url = "https://poe.com" working = True needs_auth = True diff --git a/g4f/Provider/needs_auth/Raycast.py b/g4f/Provider/needs_auth/Raycast.py index d7be98ac..07abeda3 100644 --- a/g4f/Provider/needs_auth/Raycast.py +++ b/g4f/Provider/needs_auth/Raycast.py @@ -5,10 +5,10 @@ import json import requests from ...typing import CreateResult, Messages -from ..base_provider import BaseProvider +from ..base_provider import AbstractProvider -class Raycast(BaseProvider): +class Raycast(AbstractProvider): url = "https://raycast.com" supports_gpt_35_turbo = True supports_gpt_4 = True diff --git a/g4f/Provider/needs_auth/Theb.py b/g4f/Provider/needs_auth/Theb.py index 82eac6e2..efb38a40 100644 --- a/g4f/Provider/needs_auth/Theb.py +++ b/g4f/Provider/needs_auth/Theb.py @@ -3,7 +3,7 @@ from __future__ import annotations import time from ...typing import CreateResult, Messages -from ..base_provider import BaseProvider +from ..base_provider import AbstractProvider from ..helper import format_prompt from ...webdriver import WebDriver, WebDriverSession @@ -31,7 +31,7 @@ models = { "qwen-7b-chat": "Qwen 7B" } -class Theb(BaseProvider): +class Theb(AbstractProvider): url = "https://beta.theb.ai" working = True supports_gpt_35_turbo = True diff --git a/g4f/Provider/needs_auth/ThebApi.py b/g4f/Provider/needs_auth/ThebApi.py index 0441f352..8ec7bda8 100644 --- a/g4f/Provider/needs_auth/ThebApi.py +++ b/g4f/Provider/needs_auth/ThebApi.py @@ -3,7 +3,7 @@ from __future__ import annotations import requests from ...typing import Any, CreateResult, Messages -from ..base_provider import BaseProvider +from ..base_provider import AbstractProvider models = { "theb-ai": "TheB.AI", @@ -29,7 +29,7 @@ models = { "qwen-7b-chat": "Qwen 7B" } -class ThebApi(BaseProvider): +class ThebApi(AbstractProvider): url = "https://theb.ai" working = True needs_auth = True diff --git a/g4f/Provider/retry_provider.py b/g4f/Provider/retry_provider.py index e49b6da6..4d3e77ac 100644 --- a/g4f/Provider/retry_provider.py +++ b/g4f/Provider/retry_provider.py @@ -2,26 +2,13 @@ from __future__ import annotations import asyncio import random -from typing import List, Type, Dict from ..typing import CreateResult, Messages -from .base_provider import BaseProvider, AsyncProvider +from ..base_provider import BaseRetryProvider from .. import debug from ..errors import RetryProviderError, RetryNoProviderError -class RetryProvider(AsyncProvider): - __name__: str = "RetryProvider" - supports_stream: bool = True - - def __init__( - self, - providers: List[Type[BaseProvider]], - shuffle: bool = True - ) -> None: - self.providers: List[Type[BaseProvider]] = providers - self.shuffle: bool = shuffle - self.working = True - +class RetryProvider(BaseRetryProvider): def create_completion( self, model: str, @@ -36,20 +23,18 @@ class RetryProvider(AsyncProvider): if self.shuffle: random.shuffle(providers) - self.exceptions: Dict[str, Exception] = {} + self.exceptions = {} started: bool = False for provider in providers: + self.last_provider = provider try: if debug.logging: print(f"Using {provider.__name__} provider") - for token in provider.create_completion(model, messages, stream, **kwargs): yield token started = True - if started: return - except Exception as e: self.exceptions[provider.__name__] = e if debug.logging: @@ -69,8 +54,9 @@ class RetryProvider(AsyncProvider): if self.shuffle: random.shuffle(providers) - self.exceptions: Dict[str, Exception] = {} + self.exceptions = {} for provider in providers: + self.last_provider = provider try: return await asyncio.wait_for( provider.create_async(model, messages, **kwargs), diff --git a/g4f/Provider/selenium/Phind.py b/g4f/Provider/selenium/Phind.py index 2722307d..b97d278f 100644 --- a/g4f/Provider/selenium/Phind.py +++ b/g4f/Provider/selenium/Phind.py @@ -4,11 +4,11 @@ import time from urllib.parse import quote from ...typing import CreateResult, Messages -from ..base_provider import BaseProvider +from ..base_provider import AbstractProvider from ..helper import format_prompt from ...webdriver import WebDriver, WebDriverSession -class Phind(BaseProvider): +class Phind(AbstractProvider): url = "https://www.phind.com" working = True supports_gpt_4 = True diff --git a/g4f/Provider/unfinished/AiChatting.py b/g4f/Provider/unfinished/AiChatting.py index a66921c1..f062fa98 100644 --- a/g4f/Provider/unfinished/AiChatting.py +++ b/g4f/Provider/unfinished/AiChatting.py @@ -3,11 +3,11 @@ from __future__ import annotations from urllib.parse import unquote from ...typing import AsyncResult, Messages -from ..base_provider import BaseProvider +from ..base_provider import AbstractProvider from ...webdriver import WebDriver from ...requests import Session, get_session_from_browser -class AiChatting(BaseProvider): +class AiChatting(AbstractProvider): url = "https://www.aichatting.net" supports_gpt_35_turbo = True _session: Session = None |