From cab71ca8b6e1a4771499c4a2fb445d9ea3602ed0 Mon Sep 17 00:00:00 2001 From: Heiner Lohaus Date: Tue, 26 Nov 2024 16:36:45 +0100 Subject: Add duckduckgo-search to slim requirements, Add pass provider as model in the client, Fix missing @property in version utils --- docs/async_client.md | 2 +- docs/legacy.md | 4 ++-- etc/unittest/client.py | 35 ++++++++++++++++++++++++++++++++++- etc/unittest/main.py | 11 ++++++++++- g4f/client/service.py | 10 ++++++++-- g4f/gui/client/static/js/chat.v1.js | 5 ++++- g4f/requests/__init__.py | 5 +++-- g4f/version.py | 2 +- requirements-slim.txt | 1 + 9 files changed, 64 insertions(+), 11 deletions(-) diff --git a/docs/async_client.md b/docs/async_client.md index cc4c5806..891a2356 100644 --- a/docs/async_client.md +++ b/docs/async_client.md @@ -292,7 +292,7 @@ client = AsyncClient(provider=g4f.Provider.OpenaiChat) response = await client.chat.completions.create( model="gpt-4", - provider=g4f.Provider.Bing, + provider=g4f.Provider.CopilotAccount, messages=[ { "role": "user", diff --git a/docs/legacy.md b/docs/legacy.md index d5cd5a36..393e3c39 100644 --- a/docs/legacy.md +++ b/docs/legacy.md @@ -7,7 +7,7 @@ import g4f g4f.debug.logging = True # Enable debug logging g4f.debug.version_check = False # Disable automatic version checking -print(g4f.Provider.Bing.params) # Print supported args for Bing +print(g4f.Provider.Gemini.params) # Print supported args for Bing # Using automatic a provider for the given model ## Streamed completion @@ -78,7 +78,7 @@ for message in response: Image upload and generation are supported by three main providers: -- **Bing & Other GPT-4 Providers:** Utilizes Microsoft's Image Creator. +- **Microsoft Copilot & Other GPT-4 Providers:** Utilizes Microsoft's Image Creator. - **Google Gemini:** Available for free accounts with IP addresses outside Europe. - **OpenaiChat with GPT-4:** Accessible for users with a Plus subscription. diff --git a/etc/unittest/client.py b/etc/unittest/client.py index 97f9f6c8..663d5f28 100644 --- a/etc/unittest/client.py +++ b/etc/unittest/client.py @@ -2,7 +2,10 @@ from __future__ import annotations import unittest -from g4f.client import Client, AsyncClient, ChatCompletion, ChatCompletionChunk +from g4f.errors import ModelNotFoundError +from g4f.client import Client, AsyncClient, ChatCompletion, ChatCompletionChunk, get_model_and_provider +from g4f.Provider.Copilot import Copilot +from g4f.models import gpt_4o from .mocks import AsyncGeneratorProviderMock, ModelProviderMock, YieldProviderMock DEFAULT_MESSAGES = [{'role': 'user', 'content': 'Hello'}] @@ -104,5 +107,35 @@ class TestPassModel(unittest.TestCase): self.assertIsInstance(response, ChatCompletion) self.assertEqual("How are you?", response.choices[0].message.content) + def test_model_not_found(self): + def run_exception(): + client = Client() + client.chat.completions.create(DEFAULT_MESSAGES, "Hello") + self.assertRaises(ModelNotFoundError, run_exception) + + def test_best_provider(self): + not_default_model = "gpt-4o" + model, provider = get_model_and_provider(not_default_model, None, False) + self.assertTrue(hasattr(provider, "create_completion")) + self.assertEqual(model, not_default_model) + + def test_default_model(self): + default_model = "" + model, provider = get_model_and_provider(default_model, None, False) + self.assertTrue(hasattr(provider, "create_completion")) + self.assertEqual(model, default_model) + + def test_provider_as_model(self): + provider_as_model = Copilot.__name__ + model, provider = get_model_and_provider(provider_as_model, None, False) + self.assertTrue(hasattr(provider, "create_completion")) + self.assertIsInstance(model, str) + self.assertEqual(model, Copilot.default_model) + + def test_get_model(self): + model, provider = get_model_and_provider(gpt_4o.name, None, False) + self.assertTrue(hasattr(provider, "create_completion")) + self.assertEqual(model, gpt_4o.name) + if __name__ == '__main__': unittest.main() \ No newline at end of file diff --git a/etc/unittest/main.py b/etc/unittest/main.py index a3949216..0c71aea1 100644 --- a/etc/unittest/main.py +++ b/etc/unittest/main.py @@ -1,7 +1,9 @@ import unittest import asyncio + import g4f from g4f import ChatCompletion, get_last_provider +from g4f.errors import VersionNotFoundError from g4f.Provider import RetryProvider from .mocks import ProviderMock @@ -27,4 +29,11 @@ class TestGetLastProvider(unittest.TestCase): last_provider_dict = get_last_provider(True) self.assertIsInstance(last_provider_dict, dict) self.assertIn('name', last_provider_dict) - self.assertEqual(ProviderMock.__name__, last_provider_dict['name']) \ No newline at end of file + self.assertEqual(ProviderMock.__name__, last_provider_dict['name']) + + def test_get_latest_version(self): + try: + self.assertIsInstance(g4f.version.utils.current_version, str) + except VersionNotFoundError: + pass + self.assertIsInstance(g4f.version.utils.latest_version, str) \ No newline at end of file diff --git a/g4f/client/service.py b/g4f/client/service.py index 44533ece..30aa1d6b 100644 --- a/g4f/client/service.py +++ b/g4f/client/service.py @@ -61,9 +61,15 @@ def get_model_and_provider(model : Union[Model, str], if not provider: if not model: model = default + provider = model.best_provider elif isinstance(model, str): - raise ModelNotFoundError(f'Model not found: {model}') - provider = model.best_provider + if model in ProviderUtils.convert: + provider = ProviderUtils.convert[model] + model = provider.default_model if hasattr(provider, "default_model") else "" + else: + raise ModelNotFoundError(f'Model not found: {model}') + else: + provider = model.best_provider if not provider: raise ProviderNotFoundError(f'No provider found for model: {model}') diff --git a/g4f/gui/client/static/js/chat.v1.js b/g4f/gui/client/static/js/chat.v1.js index 0bf49ac3..a1975dd0 100644 --- a/g4f/gui/client/static/js/chat.v1.js +++ b/g4f/gui/client/static/js/chat.v1.js @@ -1327,6 +1327,8 @@ async function on_api() { } async function load_version() { + let new_version = document.querySelector(".new_version"); + if (new_version) return; const versions = await api("version"); document.title = 'g4f - ' + versions["version"]; let text = "version ~ " @@ -1334,7 +1336,7 @@ async function load_version() { let release_url = 'https://github.com/xtekky/gpt4free/releases/latest'; let title = `New version: ${versions["latest_version"]}`; text += `${versions["version"]} 🆕`; - const new_version = document.createElement("div"); + new_version = document.createElement("div"); new_version.classList.add("new_version"); const link = `v${versions["latest_version"]}`; new_version.innerHTML = `g4f ${link}  ðŸ†•`; @@ -1344,6 +1346,7 @@ async function load_version() { text += versions["version"]; } document.getElementById("version_text").innerHTML = text + setTimeout(load_version, 1000 * 60 * 60); // 1 hour } setTimeout(load_version, 100); diff --git a/g4f/requests/__init__.py b/g4f/requests/__init__.py index 2e576d19..ded13866 100644 --- a/g4f/requests/__init__.py +++ b/g4f/requests/__init__.py @@ -123,6 +123,7 @@ def get_session_from_browser(url: str, webdriver: WebDriver = None, proxy: str = timeout=timeout, impersonate="chrome" ) + def get_cookie_params_from_dict(cookies: Cookies, url: str = None, domain: str = None) -> list[CookieParam]: [CookieParam.from_json({ "name": key, @@ -172,12 +173,12 @@ def merge_cookies(cookies: Iterator[Morsel], response: Response) -> Cookies: cookies = {} for cookie in response.cookies.jar: cookies[cookie.name] = cookie.value - + async def get_nodriver(proxy: str = None, **kwargs)-> Browser: if not has_nodriver: raise MissingRequirementsError('Install "nodriver" package | pip install -U nodriver') user_data_dir = user_config_dir("g4f-nodriver") if has_platformdirs else None - debug.log(f"Copilot: Open nodriver with user_dir: {user_data_dir}") + debug.log(f"Open nodriver with user_dir: {user_data_dir}") return await nodriver.start( user_data_dir=user_data_dir, browser_args=None if proxy is None else [f"--proxy-server={proxy}"], diff --git a/g4f/version.py b/g4f/version.py index 403ce370..3cde30c7 100644 --- a/g4f/version.py +++ b/g4f/version.py @@ -88,7 +88,7 @@ class VersionUtils: raise VersionNotFoundError("Version not found") - @cached_property + @property def latest_version(self) -> str: """ Retrieves the latest version of the 'g4f' package. diff --git a/requirements-slim.txt b/requirements-slim.txt index a7e105db..1ca3bd3e 100644 --- a/requirements-slim.txt +++ b/requirements-slim.txt @@ -3,6 +3,7 @@ pycryptodome curl_cffi>=0.6.2 aiohttp certifi +duckduckgo-search>=6.3.7 nest_asyncio werkzeug pillow -- cgit v1.2.3