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

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

代码差异

21 个文件 +358 -97
Modified g4f/Provider/Copilot.py +1 -0
@@ -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"]
Modified g4f/Provider/CopilotSession.py +1 -0
@@ -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
Modified g4f/Provider/DeepInfra.py +1 -1
@@ -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:
Modified g4f/Provider/Perplexity.py +15 -16
@@ -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
Modified g4f/Provider/Pollinations.py +7 -3
@@ -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,
Modified g4f/Provider/__init__.py +2 -2
@@ -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
Modified g4f/Provider/hf_space/__init__.py +1 -1
@@ -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
Modified g4f/Provider/local/Ollama.py +1 -3
@@ -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]:
Modified g4f/Provider/needs_auth/Gemini.py +1 -1
@@ -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(
Modified g4f/Provider/needs_auth/GeminiPro.py +2 -9
@@ -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
Modified g4f/Provider/needs_auth/Groq.py +0 -2
@@ -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",
Modified g4f/Provider/needs_auth/Nvidia.py +0 -2
@@ -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
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