返回提交历史
Modified
g4f/Provider/Liaobots.py
+5
-5
Modified
g4f/Provider/PollinationsAI.py
+16
-19
Modified
g4f/Provider/__init__.py
+28
-37
Modified
g4f/Provider/needs_auth/Gemini.py
+9
-6
XFEstudio/gpt4free
fix: update provider implementations and fix SSL handling
- Fix SSL parameter in Liaobots provider (change verify_ssl to ssl=False) - Simplify model aliases in PollinationsAI by removing list-based random selection - Add referrer parameter to PollinationsAI provider methods - Fix image URL generation in PollinationsAI to prevent URL length issues - Add Gemini-2.5-flash model to Gemini provider models dictionary - Add Gemini-2.5-pro alias in Gemini provider - Remove try/except blocks in Provider/__init__.py for more direct imports - Fix response_format handling in PollinationsAI provider - Update RequestLogin handling in Gemini provider
e2bb1b1f
代码差异
4 个文件
+58
-67
@@ -375,7 +375,7 @@ class Liaobots(AsyncGeneratorProvider, ProviderModelMixin):
375
375
f"{cls.url}/api/chat",
376
376
json=data,
377
377
headers={"x-auth-code": cls._auth_code},
378
verify_ssl=False
378
ssl=False
379
379
) as response:
380
380
# Check if we got a streaming response
381
381
content_type = response.headers.get("Content-Type", "")
@@ -416,7 +416,7 @@ class Liaobots(AsyncGeneratorProvider, ProviderModelMixin):
416
416
f"{cls.url}/api/chat",
417
417
json=data,
418
418
headers={"x-auth-code": cls._auth_code},
419
verify_ssl=False
419
ssl=False
420
420
) as response2:
421
421
# Check if we got a streaming response
422
422
content_type = response2.headers.get("Content-Type", "")
@@ -462,7 +462,7 @@ class Liaobots(AsyncGeneratorProvider, ProviderModelMixin):
462
462
async with session.post(
463
463
f"{cls.url}/recaptcha/api/login",
464
464
json={"token": "abcdefghijklmnopqrst"},
465
verify_ssl=False
465
ssl=False
466
466
) as response:
467
467
if response.status == 200:
468
468
try:
@@ -497,7 +497,7 @@ class Liaobots(AsyncGeneratorProvider, ProviderModelMixin):
497
497
async with session.post(
498
498
f"{cls.url}/api/user",
499
499
json=auth_request_data,
500
verify_ssl=False
500
ssl=False
501
501
) as response:
502
502
if response.status == 200:
503
503
response_text = await response.text()
@@ -518,7 +518,7 @@ class Liaobots(AsyncGeneratorProvider, ProviderModelMixin):
518
518
async with session.post(
519
519
f"{cls.url}/api/user",
520
520
json=auth_request_data,
521
verify_ssl=False
521
ssl=False
522
522
) as response2:
523
523
if response2.status == 200:
524
524
response_text2 = await response2.text()
@@ -57,12 +57,12 @@ class PollinationsAI(AsyncGeneratorProvider, ProviderModelMixin):
57
57
model_aliases = {
58
58
### Text Models ###
59
59
"gpt-4o-mini": "openai",
60
"gpt-4.1-nano": ["openai-fast", "openai-small"],
60
"gpt-4.1-nano": "openai-fast",
61
61
"gpt-4": "openai-large",
62
62
"gpt-4o": "openai-large",
63
"gpt-4.1": ["openai", "openai-large", "openai-xlarge"],
63
"gpt-4.1": "openai-large",
64
64
"o4-mini": "openai-reasoning",
65
"gpt-4.1-mini": ["openai", "openai-roblox", "roblox-rp"],
65
"gpt-4.1-mini": "openai",
66
66
"command-r-plus-08-2024": "command-r",
67
67
"gemini-2.5-flash": "gemini",
68
68
"gemini-2.0-flash-thinking": "gemini-thinking",
@@ -71,7 +71,7 @@ class PollinationsAI(AsyncGeneratorProvider, ProviderModelMixin):
71
71
"llama-4-scout": "llamascout",
72
72
"llama-4-scout-17b": "llamascout",
73
73
"mistral-small-3.1-24b": "mistral",
74
"deepseek-r1": ["deepseek-reasoning-large", "deepseek-reasoning"],
74
"deepseek-r1": "deepseek-reasoning-large",
75
75
"deepseek-r1-distill-llama-70b": "deepseek-reasoning-large",
76
76
"deepseek-r1-distill-llama-70b": "deepseek-r1-llama",
77
77
#"mistral-small-3.1-24b": "unity", # Personas
@@ -93,7 +93,6 @@ class PollinationsAI(AsyncGeneratorProvider, ProviderModelMixin):
93
93
94
94
### Audio Models ###
95
95
"gpt-4o-audio": "openai-audio",
96
#"gpt-4o-audio-preview": "openai-audio",
97
96
98
97
### Image Models ###
99
98
"sdxl-turbo": "turbo",
@@ -111,11 +110,7 @@ class PollinationsAI(AsyncGeneratorProvider, ProviderModelMixin):
111
110
112
111
# Check if there's an alias for this model
113
112
if model in cls.model_aliases:
114
alias = cls.model_aliases[model]
115
# If the alias is a list, randomly select one of the options
116
if isinstance(alias, list):
117
return random.choice(alias)
118
return alias
113
return cls.model_aliases[model]
119
114
120
115
# If no match is found, raise an error
121
116
raise ModelNotFoundError(f"Model {model} not found")
@@ -197,6 +192,7 @@ class PollinationsAI(AsyncGeneratorProvider, ProviderModelMixin):
197
192
stream: bool = True,
198
193
proxy: str = None,
199
194
cache: bool = False,
195
referrer: str = "https://gpt4free.github.io/",
200
196
# Image generation parameters
201
197
prompt: str = None,
202
198
aspect_ratio: str = "1:1",
@@ -247,7 +243,8 @@ class PollinationsAI(AsyncGeneratorProvider, ProviderModelMixin):
247
243
private=private,
248
244
enhance=enhance,
249
245
safe=safe,
250
n=n
246
n=n,
247
referrer=referrer
251
248
):
252
249
yield chunk
253
250
else:
@@ -275,6 +272,7 @@ class PollinationsAI(AsyncGeneratorProvider, ProviderModelMixin):
275
272
cache=cache,
276
273
stream=stream,
277
274
extra_parameters=extra_parameters,
275
referrer=referrer,
278
276
**kwargs
279
277
):
280
278
yield result
@@ -294,7 +292,8 @@ class PollinationsAI(AsyncGeneratorProvider, ProviderModelMixin):
294
292
private: bool,
295
293
enhance: bool,
296
294
safe: bool,
297
n: int
295
n: int,
296
referrer: str
298
297
) -> AsyncResult:
299
298
params = use_aspect_ratio({
300
299
"width": width,
@@ -306,7 +305,7 @@ class PollinationsAI(AsyncGeneratorProvider, ProviderModelMixin):
306
305
"safe": str(safe).lower()
307
306
}, aspect_ratio)
308
307
query = "&".join(f"{k}={quote_plus(str(v))}" for k, v in params.items() if v is not None)
309
prompt = quote_plus(prompt)[:2048-256-len(query)]
308
prompt = quote_plus(prompt)[:2048-len(cls.image_api_endpoint)-len(query)-8]
310
309
url = f"{cls.image_api_endpoint}prompt/{prompt}?{query}"
311
310
def get_image_url(i: int, seed: Optional[int] = None):
312
311
if i == 1:
@@ -317,7 +316,7 @@ class PollinationsAI(AsyncGeneratorProvider, ProviderModelMixin):
317
316
return f"{url}&seed={seed}" if seed else url
318
317
async with ClientSession(headers=DEFAULT_HEADERS, connector=get_connector(proxy=proxy)) as session:
319
318
async def get_image(i: int, seed: Optional[int] = None):
320
async with session.get(get_image_url(i, seed), allow_redirects=False) as response:
319
async with session.get(get_image_url(i, seed), allow_redirects=False, headers={"referer": referrer}) as response:
321
320
try:
322
321
await raise_for_status(response)
323
322
except Exception as e:
@@ -344,13 +343,11 @@ class PollinationsAI(AsyncGeneratorProvider, ProviderModelMixin):
344
343
cache: bool,
345
344
stream: bool,
346
345
extra_parameters: list[str],
346
referrer: str,
347
347
**kwargs
348
348
) -> AsyncResult:
349
349
if not cache and seed is None:
350
350
seed = random.randint(0, 2**32)
351
json_mode = False
352
if response_format and response_format.get("type") == "json_object":
353
json_mode = True
354
351
355
352
async with ClientSession(headers=DEFAULT_HEADERS, connector=get_connector(proxy=proxy)) as session:
356
353
if model in cls.audio_models:
@@ -368,13 +365,13 @@ class PollinationsAI(AsyncGeneratorProvider, ProviderModelMixin):
368
365
"presence_penalty": presence_penalty,
369
366
"top_p": top_p,
370
367
"frequency_penalty": frequency_penalty,
371
"jsonMode": json_mode,
368
"response_format": response_format,
372
369
"stream": stream,
373
370
"seed": seed,
374
371
"cache": cache,
375
372
**extra_parameters
376
373
})
377
async with session.post(url, json=data) as response:
374
async with session.post(url, json=data, headers={"referer": referrer}) as response:
378
375
await raise_for_status(response)
379
376
if response.headers["content-type"].startswith("text/plain"):
380
377
yield await response.text()
@@ -34,43 +34,34 @@ try:
34
34
except ImportError as e:
35
35
debug.error("Audio providers not loaded:", e)
36
36
37
try:
38
from .ARTA import ARTA
39
from .Blackbox import Blackbox
40
from .Chatai import Chatai
41
from .ChatGLM import ChatGLM
42
from .ChatGpt import ChatGpt
43
from .Cloudflare import Cloudflare
44
from .Copilot import Copilot
45
from .DDG import DDG
46
from .DeepInfraChat import DeepInfraChat
47
from .DuckDuckGo import DuckDuckGo
48
from .Dynaspark import Dynaspark
49
except ImportError as e:
50
debug.error("Providers not loaded (A-D):", e)
51
try:
52
from .Free2GPT import Free2GPT
53
from .FreeGpt import FreeGpt
54
from .GizAI import GizAI
55
from .ImageLabs import ImageLabs
56
from .LambdaChat import LambdaChat
57
from .Liaobots import Liaobots
58
from .LMArenaProvider import LMArenaProvider
59
except ImportError as e:
60
debug.error("Providers not loaded (F-L):", e)
61
try:
62
from .PerplexityLabs import PerplexityLabs
63
from .Pi import Pi
64
from .Pizzagpt import Pizzagpt
65
from .PollinationsAI import PollinationsAI
66
from .PollinationsImage import PollinationsImage
67
from .TeachAnything import TeachAnything
68
from .TypeGPT import TypeGPT
69
from .You import You
70
from .Websim import Websim
71
from .Yqcloud import Yqcloud
72
except ImportError as e:
73
debug.error("Providers not loaded (M-Z):", e)
37
from .ARTA import ARTA
38
from .Blackbox import Blackbox
39
from .Chatai import Chatai
40
from .ChatGLM import ChatGLM
41
from .ChatGpt import ChatGpt
42
from .Cloudflare import Cloudflare
43
from .Copilot import Copilot
44
from .DDG import DDG
45
from .DeepInfraChat import DeepInfraChat
46
from .DuckDuckGo import DuckDuckGo
47
from .Dynaspark import Dynaspark
48
from .Free2GPT import Free2GPT
49
from .FreeGpt import FreeGpt
50
from .GizAI import GizAI
51
from .ImageLabs import ImageLabs
52
from .LambdaChat import LambdaChat
53
from .Liaobots import Liaobots
54
from .LMArenaProvider import LMArenaProvider
55
from .PerplexityLabs import PerplexityLabs
56
from .Pi import Pi
57
from .Pizzagpt import Pizzagpt
58
from .PollinationsAI import PollinationsAI
59
from .PollinationsImage import PollinationsImage
60
from .TeachAnything import TeachAnything
61
from .TypeGPT import TypeGPT
62
from .You import You
63
from .Websim import Websim
64
from .Yqcloud import Yqcloud
74
65
75
66
import sys
76
67
@@ -63,6 +63,7 @@ GGOGLE_SID_COOKIE = "__Secure-1PSID"
63
63
64
64
models = {
65
65
"gemini-2.5-pro-exp": {"x-goog-ext-525001261-jspb": '[1,null,null,null,"2525e3954d185b3c"]'},
66
"gemini-2.5-flash": {"x-goog-ext-525001261-jspb": '[1,null,null,null,"35609594dbe934d8"]'},
66
67
"gemini-2.0-flash-thinking-exp": {"x-goog-ext-525001261-jspb": '[1,null,null,null,"7ca48d02d802f20a"]'},
67
68
"gemini-deep-research": {"x-goog-ext-525001261-jspb": '[1,null,null,null,"cd472a54d2abba7e"]'},
68
69
"gemini-2.0-flash": {"x-goog-ext-525001261-jspb": '[null,null,null,null,"f299729663a2343f"]'},
@@ -87,7 +88,10 @@ class Gemini(AsyncGeneratorProvider, ProviderModelMixin):
87
88
models = [
88
89
default_model, *models.keys()
89
90
]
90
model_aliases = {"gemini-2.0": ""}
91
model_aliases = {
92
"gemini-2.0": "",
93
"gemini-2.5-pro": "gemini-2.5-pro-exp"
94
}
91
95
92
96
synthesize_content_type = "audio/vnd.wav"
93
97
@@ -102,14 +106,11 @@ class Gemini(AsyncGeneratorProvider, ProviderModelMixin):
102
106
@classmethod
103
107
async def nodriver_login(cls, proxy: str = None) -> AsyncIterator[str]:
104
108
if not has_nodriver:
105
if debug.logging:
106
print("Skip nodriver login in Gemini provider")
109
debug.log("Skip nodriver login in Gemini provider")
107
110
return
108
111
browser, stop_browser = await get_nodriver(proxy=proxy, user_data_dir="gemini")
109
112
try:
110
login_url = os.environ.get("G4F_LOGIN_URL")
111
if login_url:
112
yield RequestLogin(cls.label, login_url)
113
yield RequestLogin(cls.label, os.environ.get("G4F_LOGIN_URL", ""))
113
114
page = await browser.get(f"{cls.url}/app")
114
115
await page.select("div.ql-editor.textarea", 240)
115
116
cookies = {}
@@ -159,6 +160,8 @@ class Gemini(AsyncGeneratorProvider, ProviderModelMixin):
159
160
audio: dict = None,
160
161
**kwargs
161
162
) -> AsyncResult:
163
if model in cls.model_aliases:
164
model = cls.model_aliases[model]
162
165
if audio is not None or model == "gemini-audio":
163
166
prompt = format_image_prompt(messages, prompt)
164
167
filename = get_filename(["gemini"], prompt, ".ogx", prompt)