返回提交历史
Modified
g4f/Provider/Copilot.py
+1
-0
Modified
g4f/Provider/CopilotSession.py
+1
-0
Modified
g4f/Provider/DeepInfra.py
+1
-1
Modified
g4f/Provider/Perplexity.py
+15
-16
Modified
g4f/Provider/Pollinations.py
+7
-3
Modified
g4f/Provider/__init__.py
+2
-2
Modified
g4f/Provider/hf_space/__init__.py
+1
-1
Modified
g4f/Provider/local/Ollama.py
+1
-3
Modified
g4f/Provider/needs_auth/Gemini.py
+1
-1
Modified
g4f/Provider/needs_auth/GeminiPro.py
+2
-9
Modified
g4f/Provider/needs_auth/Groq.py
+0
-2
Modified
g4f/Provider/needs_auth/Nvidia.py
+0
-2
Modified
g4f/Provider/search/GoogleSearch.py
+65
-33
Modified
g4f/Provider/template/OpenaiTemplate.py
+37
-17
Modified
g4f/api/__init__.py
+28
-0
Modified
g4f/client/factory.py
+2
-0
Modified
g4f/gui/server/backend_api.py
+9
-3
Modified
g4f/models.py
+0
-1
Modified
g4f/providers/base_provider.py
+16
-0
Modified
g4f/providers/response.py
+19
-0
Modified
g4f/requests/cdp.py
+150
-3
XFEstudio/gpt4free
Add authentication requirements and improve screenshot functionality across providers
- Set `needs_auth` to True for Copilot and CopilotSession providers. - Update DeepInfra to run in headless mode. - Refactor Perplexity provider to enhance response handling. - Introduce new base URL and endpoints for Pollinations provider. - Implement screenshot capturing functionality in CDPSession with caching. - Enhance GoogleSearch provider to support native tools and improve search result extraction. - Clean up unused models and variables in various providers.
fd340310
代码差异
21 个文件
+358
-97
@@ -94,6 +94,7 @@ class Copilot(AsyncAuthedProvider, ProviderModelMixin):
94
94
95
95
working = True
96
96
use_nodriver = has_nodriver
97
needs_auth = True
97
98
98
99
default_model = "Copilot"
99
100
models = [default_model, "Think Deeper", "Smart (GPT-5)", "Study"]
@@ -54,6 +54,7 @@ class CopilotSession(AsyncAuthedProvider, ProviderModelMixin):
54
54
55
55
working = has_nodriver
56
56
use_nodriver = has_nodriver
57
needs_auth = True
57
58
active_by_default = True
58
59
use_stream_timeout = False
59
60
@@ -17,7 +17,7 @@ def _get_turnstile_token_sync(model: str) -> str:
17
17
import time
18
18
19
19
for attempt in range(1):
20
session = SyncCDPSession(headless=False)
20
session = SyncCDPSession(headless=True)
21
21
session.start_chrome()
22
22
23
23
try:
@@ -102,16 +102,6 @@ class Perplexity(AsyncGeneratorProvider, ProviderModelMixin):
102
102
"r1-1776": "r1",
103
103
}
104
104
105
@classmethod
106
async def get_quota(cls, **kwargs):
107
chunks = []
108
async for chunk in cls.create_async_generator(
109
cls.default_model, [{"role": "user", "content": "say only okay"}]
110
):
111
if isinstance(chunk, str):
112
return {"content": chunk}
113
raise RuntimeError("No response")
114
115
105
@classmethod
116
106
async def create_async_generator(
117
107
cls,
@@ -446,6 +436,13 @@ class Perplexity(AsyncGeneratorProvider, ProviderModelMixin):
446
436
)
447
437
continue
448
438
439
if block.get("intended_usage") == "ask_text":
440
chunk = "".join(block.get("markdown_block", {}).get("chunks", []))
441
if chunk and (not full_response or not full_response.endswith(chunk)) and not full_reasoning.startswith(chunk):
442
if not full_response or not chunk.startswith(full_response):
443
full_response += chunk
444
yield chunk
445
449
446
# Handle response text
450
447
for patch in block.get("diff_block", {}).get("patches", []):
451
448
if patch.get("path") == "/progress":
@@ -479,11 +476,13 @@ class Perplexity(AsyncGeneratorProvider, ProviderModelMixin):
479
476
)
480
477
481
478
if value and isinstance(value, str):
482
if value.startswith(full_response):
483
value = value[len(full_response) :]
484
elif full_response.endswith(value):
485
value = ""
486
if value:
479
if full_response and full_response.startswith(value):
480
pass
481
elif full_response and full_response.endswith(value):
482
pass
483
elif full_response and value.startswith(full_response):
484
pass
485
elif value:
487
486
full_response += value
488
487
yield value
489
488
@@ -500,7 +499,7 @@ class Perplexity(AsyncGeneratorProvider, ProviderModelMixin):
500
499
"name": f"Perplexity - {conversation.thread_title}",
501
500
"url": f"{cls.url}/search/{conversation.thread_url_slug}",
502
501
}
503
]
502
] if hasattr(conversation, "thread_title") and hasattr(conversation, "thread_url_slug") else []
504
503
+ sources
505
504
)
506
505
yield conversation
@@ -40,6 +40,7 @@ class Pollinations(AsyncGeneratorProvider, ProviderModelMixin):
40
40
label = "Pollinations 🌸"
41
41
url = "https://pollinations.ai"
42
42
login_url = "https://enter.pollinations.ai"
43
base_url = "https://gen.pollinations.ai/v1"
43
44
backup_url = "https://g4f.space/api/pollinations"
44
45
active_by_default = True
45
46
working = True
@@ -50,6 +51,7 @@ class Pollinations(AsyncGeneratorProvider, ProviderModelMixin):
50
51
image_models_endpoint = "https://image.pollinations.ai/models"
51
52
gen_image_api_endpoint = "https://gen.pollinations.ai/image/{}"
52
53
gen_text_api_endpoint = "https://gen.pollinations.ai/v1/chat/completions"
54
gen_text_models_endpoint = "https://gen.pollinations.ai/text/models"
53
55
gen_image_models_endpoint = "https://gen.pollinations.ai/image/models"
54
56
quota_url = "https://g4f.space/api/pollinations/quota"
55
57
worker_api_endpoint = "https://g4f.space/api/pollinations/chat/completions"
@@ -103,7 +105,7 @@ class Pollinations(AsyncGeneratorProvider, ProviderModelMixin):
103
105
api_key = AuthManager.load_api_key(cls)
104
106
if (OpenaiTemplate.is_provider_api_key(api_key)):
105
107
debug.log(f"Using Pollinations with provided API key.")
106
models_url = cls.gen_text_api_endpoint
108
models_url = cls.gen_text_models_endpoint
107
109
image_url = cls.gen_image_models_endpoint
108
110
else:
109
111
debug.log(f"Authenticated with Pollinations using G4F API.")
@@ -544,8 +546,10 @@ class Pollinations(AsyncGeneratorProvider, ProviderModelMixin):
544
546
headers = {"authorization": f"Bearer {api_key}"}
545
547
yield JsonRequest.from_dict(data)
546
548
async with session.post(endpoint, json=data, headers=headers) as response:
547
if response.status in (400, 500):
548
debug.error(f"Error: {response.status} - Bad Request: {data}")
549
if response.status in (400, 404, 500):
550
body = json.dumps(data)
551
stripped_body = f"{body[:200]}...{body[-200:]}" if len(body) > 500 else body[:200] if len(body) > 200 else body
552
debug.error(f"Error: {response.status} - Bad Request: {stripped_body}")
549
553
async for chunk in read_response(
550
554
response,
551
555
stream,
@@ -8,7 +8,6 @@ from ..providers.create_images import CreateImagesProvider
8
8
9
9
class ProviderLoader:
10
10
names = [
11
"AnyProvider",
12
11
"AIBadgr",
13
12
"Anthropic",
14
13
"Antigravity",
@@ -34,7 +33,6 @@ class ProviderLoader:
34
33
"EdgeTTS",
35
34
"ElevenLabs",
36
35
"FenayAI",
37
"G4FSpace",
38
36
"GLM",
39
37
"Gemini",
40
38
"GeminiCLI",
@@ -507,6 +505,7 @@ class ProviderLoader:
507
505
508
506
509
507
__all__ = [
508
"AnyProvider",
510
509
"BaseProvider",
511
510
"ProviderType",
512
511
"RetryProvider",
@@ -516,6 +515,7 @@ __all__ = [
516
515
"AsyncGeneratorProvider",
517
516
"CreateImagesProvider",
518
517
"ProviderUtils",
518
"G4FSpace",
519
519
"__providers__",
520
520
"__map__",
521
521
] + ProviderLoader.names
@@ -68,7 +68,7 @@ class HuggingSpace(AsyncGeneratorProvider, ProviderModelMixin):
68
68
is_started = False
69
69
random.shuffle(cls.providers)
70
70
for provider in cls.providers:
71
if model in provider.model_aliases or model in provider.get_models():
71
if model in getattr(provider, "model_aliases", {}) or model in provider.get_models():
72
72
alias = (
73
73
provider.model_aliases[model]
74
74
if model in provider.model_aliases
@@ -18,14 +18,12 @@ from ...errors import MissingAuthError
18
18
class Ollama(OpenaiTemplate):
19
19
label = "Ollama 🦙"
20
20
url = "https://ollama.com"
21
base_url = "https://g4f.space/api/ollama"
21
backup_url = "https://g4f.space/api/ollama"
22
22
login_url = "https://ollama.com/settings/keys"
23
needs_auth = False
24
23
working = True
25
24
active_by_default = True
26
25
local_models: list[str] = []
27
26
model_aliases = {"gpt-oss-120b": "gpt-oss:120b", "gpt-oss-20b": "gpt-oss:20b"}
28
default_model = "nemotron-3-nano:30b"
29
27
30
28
@classmethod
31
29
async def get_quota(cls, api_key: Optional[str] = None) -> Optional[dict]:
@@ -537,7 +537,7 @@ class Gemini(AsyncGeneratorProvider, ProviderModelMixin):
537
537
**RESPONSE_HEADER_LIMITS,
538
538
) as session:
539
539
await cls.fetch_snlm0e(session, cls._cookies)
540
return cls._snlm0e
540
return {"sid": cls._sid, "bl": cls._bl, "push_id": cls._upload_push_id}
541
541
542
542
@classmethod
543
543
async def get_models(
@@ -8,16 +8,9 @@ class GeminiPro(OpenaiTemplate):
8
8
url = "https://ai.google.dev"
9
9
login_url = "https://aistudio.google.com/u/0/apikey"
10
10
base_url = "https://generativelanguage.googleapis.com/v1beta/openai"
11
backup_url = "https://g4f.space/api/gemini-v1beta"
11
backup_url = "https://g4f.space/api/gemini"
12
12
quota_url = backup_url + "/quota"
13
13
active_by_default = True
14
14
working = True
15
default_model = "models/gemini-2.5-flash"
16
default_vision_model = default_model
17
model_aliases = {
18
"gemini-2.5-pro": "models/gemini-2.5-pro",
19
"gemini-2.5-flash": "models/gemini-2.5-flash",
20
"gemini-2.0-flash": "models/gemini-2.0-flash",
21
"gemini-2.0-flash-thinking": "models/gemini-2.0-flash-thinking",
22
}
23
15
models_needs_auth = True
16
add_thought_signature = True
@@ -1,7 +1,6 @@
1
1
from __future__ import annotations
2
2
3
3
from ..template import OpenaiTemplate
4
from ...config import DEFAULT_MODEL
5
4
6
5
7
6
class Groq(OpenaiTemplate):
@@ -11,7 +10,6 @@ class Groq(OpenaiTemplate):
11
10
backup_url = "https://g4f.space/api/groq"
12
11
working = True
13
12
active_by_default = True
14
default_model = DEFAULT_MODEL
15
13
model_aliases = {
16
14
"mixtral-8x7b": "mixtral-8x7b-32768",
17
15
"llama2-70b": "llama2-70b-4096",
@@ -4,12 +4,10 @@ from ..template import OpenaiTemplate
4
4
5
5
6
6
class Nvidia(OpenaiTemplate):
7
label = "Nvidia"
8
7
base_url = "https://integrate.api.nvidia.com/v1"
9
8
backup_url = "https://g4f.space/api/nvidia"
10
9
login_url = "https://google.com"
11
10
url = "https://build.nvidia.com"
12
11
working = True
13
12
active_by_default = True
14
default_model = "nvidia/nemotron-3.5-lightning-30b-a3b"
15
13
add_user = False