XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet
公开
关注 0 Fork 0 Star 1
返回提交历史

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
hlohaus <983577+hlohaus@users.noreply.github.com>
提交于

代码差异

4 个文件 +58 -67
Modified g4f/Provider/Liaobots.py +5 -5
@@ -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()
Modified g4f/Provider/PollinationsAI.py +16 -19
@@ -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()
Modified g4f/Provider/__init__.py +28 -37
@@ -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
Modified g4f/Provider/needs_auth/Gemini.py +9 -6
@@ -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)