返回提交历史
Modified
docs/async_client.md
+1
-1
Modified
docs/legacy.md
+2
-2
Modified
etc/unittest/client.py
+34
-1
Modified
etc/unittest/main.py
+10
-1
Modified
g4f/client/service.py
+8
-2
Modified
g4f/gui/client/static/js/chat.v1.js
+4
-1
Modified
g4f/requests/__init__.py
+3
-2
Modified
g4f/version.py
+1
-1
Modified
requirements-slim.txt
+1
-0
XFEstudio/gpt4free
Add duckduckgo-search to slim requirements, Add pass provider as model in the client, Fix missing @property in version utils
cab71ca8
代码差异
9 个文件
+64
-11
@@ -292,7 +292,7 @@ client = AsyncClient(provider=g4f.Provider.OpenaiChat)
292
292
293
293
response = await client.chat.completions.create(
294
294
model="gpt-4",
295
provider=g4f.Provider.Bing,
295
provider=g4f.Provider.CopilotAccount,
296
296
messages=[
297
297
{
298
298
"role": "user",
@@ -7,7 +7,7 @@ import g4f
7
7
8
8
g4f.debug.logging = True # Enable debug logging
9
9
g4f.debug.version_check = False # Disable automatic version checking
10
print(g4f.Provider.Bing.params) # Print supported args for Bing
10
print(g4f.Provider.Gemini.params) # Print supported args for Bing
11
11
12
12
# Using automatic a provider for the given model
13
13
## Streamed completion
@@ -78,7 +78,7 @@ for message in response:
78
78
79
79
Image upload and generation are supported by three main providers:
80
80
81
- **Bing & Other GPT-4 Providers:** Utilizes Microsoft's Image Creator.
81
- **Microsoft Copilot & Other GPT-4 Providers:** Utilizes Microsoft's Image Creator.
82
82
- **Google Gemini:** Available for free accounts with IP addresses outside Europe.
83
83
- **OpenaiChat with GPT-4:** Accessible for users with a Plus subscription.
84
84
@@ -2,7 +2,10 @@ from __future__ import annotations
2
2
3
3
import unittest
4
4
5
from g4f.client import Client, AsyncClient, ChatCompletion, ChatCompletionChunk
5
from g4f.errors import ModelNotFoundError
6
from g4f.client import Client, AsyncClient, ChatCompletion, ChatCompletionChunk, get_model_and_provider
7
from g4f.Provider.Copilot import Copilot
8
from g4f.models import gpt_4o
6
9
from .mocks import AsyncGeneratorProviderMock, ModelProviderMock, YieldProviderMock
7
10
8
11
DEFAULT_MESSAGES = [{'role': 'user', 'content': 'Hello'}]
@@ -104,5 +107,35 @@ class TestPassModel(unittest.TestCase):
104
107
self.assertIsInstance(response, ChatCompletion)
105
108
self.assertEqual("How are you?", response.choices[0].message.content)
106
109
110
def test_model_not_found(self):
111
def run_exception():
112
client = Client()
113
client.chat.completions.create(DEFAULT_MESSAGES, "Hello")
114
self.assertRaises(ModelNotFoundError, run_exception)
115
116
def test_best_provider(self):
117
not_default_model = "gpt-4o"
118
model, provider = get_model_and_provider(not_default_model, None, False)
119
self.assertTrue(hasattr(provider, "create_completion"))
120
self.assertEqual(model, not_default_model)
121
122
def test_default_model(self):
123
default_model = ""
124
model, provider = get_model_and_provider(default_model, None, False)
125
self.assertTrue(hasattr(provider, "create_completion"))
126
self.assertEqual(model, default_model)
127
128
def test_provider_as_model(self):
129
provider_as_model = Copilot.__name__
130
model, provider = get_model_and_provider(provider_as_model, None, False)
131
self.assertTrue(hasattr(provider, "create_completion"))
132
self.assertIsInstance(model, str)
133
self.assertEqual(model, Copilot.default_model)
134
135
def test_get_model(self):
136
model, provider = get_model_and_provider(gpt_4o.name, None, False)
137
self.assertTrue(hasattr(provider, "create_completion"))
138
self.assertEqual(model, gpt_4o.name)
139
107
140
if __name__ == '__main__':
108
141
unittest.main()
@@ -1,7 +1,9 @@
1
1
import unittest
2
2
import asyncio
3
3
4
import g4f
4
5
from g4f import ChatCompletion, get_last_provider
6
from g4f.errors import VersionNotFoundError
5
7
from g4f.Provider import RetryProvider
6
8
from .mocks import ProviderMock
7
9
@@ -27,4 +29,11 @@ class TestGetLastProvider(unittest.TestCase):
27
29
last_provider_dict = get_last_provider(True)
28
30
self.assertIsInstance(last_provider_dict, dict)
29
31
self.assertIn('name', last_provider_dict)
30
self.assertEqual(ProviderMock.__name__, last_provider_dict['name'])
32
self.assertEqual(ProviderMock.__name__, last_provider_dict['name'])
33
34
def test_get_latest_version(self):
35
try:
36
self.assertIsInstance(g4f.version.utils.current_version, str)
37
except VersionNotFoundError:
38
pass
39
self.assertIsInstance(g4f.version.utils.latest_version, str)
@@ -61,9 +61,15 @@ def get_model_and_provider(model : Union[Model, str],
61
61
if not provider:
62
62
if not model:
63
63
model = default
64
provider = model.best_provider
64
65
elif isinstance(model, str):
65
raise ModelNotFoundError(f'Model not found: {model}')
66
provider = model.best_provider
66
if model in ProviderUtils.convert:
67
provider = ProviderUtils.convert[model]
68
model = provider.default_model if hasattr(provider, "default_model") else ""
69
else:
70
raise ModelNotFoundError(f'Model not found: {model}')
71
else:
72
provider = model.best_provider
67
73
68
74
if not provider:
69
75
raise ProviderNotFoundError(f'No provider found for model: {model}')
@@ -1327,6 +1327,8 @@ async function on_api() {
1327
1327
}
1328
1328
1329
1329
async function load_version() {
1330
let new_version = document.querySelector(".new_version");
1331
if (new_version) return;
1330
1332
const versions = await api("version");
1331
1333
document.title = 'g4f - ' + versions["version"];
1332
1334
let text = "version ~ "
@@ -1334,7 +1336,7 @@ async function load_version() {
1334
1336
let release_url = 'https://github.com/xtekky/gpt4free/releases/latest';
1335
1337
let title = `New version: ${versions["latest_version"]}`;
1336
1338
text += `<a href="${release_url}" target="_blank" title="${title}">${versions["version"]}</a> 🆕`;
1337
const new_version = document.createElement("div");
1339
new_version = document.createElement("div");
1338
1340
new_version.classList.add("new_version");
1339
1341
const link = `<a href="${release_url}" target="_blank" title="${title}">v${versions["latest_version"]}</a>`;
1340
1342
new_version.innerHTML = `g4f ${link} 🆕`;
@@ -1344,6 +1346,7 @@ async function load_version() {
1344
1346
text += versions["version"];
1345
1347
}
1346
1348
document.getElementById("version_text").innerHTML = text
1349
setTimeout(load_version, 1000 * 60 * 60); // 1 hour
1347
1350
}
1348
1351
setTimeout(load_version, 100);
1349
1352
@@ -123,6 +123,7 @@ def get_session_from_browser(url: str, webdriver: WebDriver = None, proxy: str =
123
123
timeout=timeout,
124
124
impersonate="chrome"
125
125
)
126
126
127
def get_cookie_params_from_dict(cookies: Cookies, url: str = None, domain: str = None) -> list[CookieParam]:
127
128
[CookieParam.from_json({
128
129
"name": key,
@@ -172,12 +173,12 @@ def merge_cookies(cookies: Iterator[Morsel], response: Response) -> Cookies:
172
173
cookies = {}
173
174
for cookie in response.cookies.jar:
174
175
cookies[cookie.name] = cookie.value
175
176
176
177
async def get_nodriver(proxy: str = None, **kwargs)-> Browser:
177
178
if not has_nodriver:
178
179
raise MissingRequirementsError('Install "nodriver" package | pip install -U nodriver')
179
180
user_data_dir = user_config_dir("g4f-nodriver") if has_platformdirs else None
180
debug.log(f"Copilot: Open nodriver with user_dir: {user_data_dir}")
181
debug.log(f"Open nodriver with user_dir: {user_data_dir}")
181
182
return await nodriver.start(
182
183
user_data_dir=user_data_dir,
183
184
browser_args=None if proxy is None else [f"--proxy-server={proxy}"],
@@ -88,7 +88,7 @@ class VersionUtils:
88
88
89
89
raise VersionNotFoundError("Version not found")
90
90
91
@cached_property
91
@property
92
92
def latest_version(self) -> str:
93
93
"""
94
94
Retrieves the latest version of the 'g4f' package.
@@ -3,6 +3,7 @@ pycryptodome
3
3
curl_cffi>=0.6.2
4
4
aiohttp
5
5
certifi
6
duckduckgo-search>=6.3.7
6
7
nest_asyncio
7
8
werkzeug
8
9
pillow