返回提交历史
Modified
g4f/Provider/PollinationsAI.py
+62
-35
Modified
g4f/Provider/local/Ollama.py
+0
-1
Modified
g4f/Provider/needs_auth/Azure.py
+0
-1
Modified
g4f/Provider/needs_auth/Groq.py
+0
-1
Modified
g4f/Provider/needs_auth/Nvidia.py
+0
-1
Modified
g4f/Provider/needs_auth/OpenRouter.py
+0
-1
XFEstudio/gpt4free
Remove backup URLs from multiple provider classes to streamline code
0049b8ef
代码差异
6 个文件
+62
-40
@@ -31,18 +31,20 @@ class PollinationsAI(AsyncGeneratorProvider, ProviderModelMixin):
31
31
label = "Pollinations AI 🌸"
32
32
url = "https://pollinations.ai"
33
33
login_url = "https://enter.pollinations.ai"
34
api_key = "pk", "_B9YJX5SBohhm2ePq"
34
35
active_by_default = True
35
36
working = True
36
37
supports_system_message = True
37
38
supports_message_history = True
38
39
39
40
# API endpoints
40
text_api_endpoint = "https://g4f.dev/api/pollinations/chat/completions"
41
text_api_endpoint = "https://text.pollinations.ai/openai"
41
42
image_api_endpoint = "https://image.pollinations.ai/prompt/{}"
42
43
gen_image_api_endpoint = "https://gen.pollinations.ai/image/{}"
43
44
gen_text_api_endpoint = "https://gen.pollinations.ai/v1/chat/completions"
44
45
image_models_endpoint = "https://gen.pollinations.ai/image/models"
45
46
text_models_endpoint = "https://gen.pollinations.ai/text/models"
47
BALANCE_ENDPOINT = "https://gen.pollinations.ai/account/balance"
46
48
47
49
# Models configuration
48
50
default_model = "openai"
@@ -71,6 +73,21 @@ class PollinationsAI(AsyncGeneratorProvider, ProviderModelMixin):
71
73
"flux-kontext": "kontext",
72
74
}
73
75
swap_model_aliases = {v: k for k, v in model_aliases.items()}
76
balance: Optional[float] = None
77
78
@classmethod
79
def get_balance(cls, api_key: str, timeout: Optional[float] = None) -> Optional[float]:
80
try:
81
headers = {"authorization": f"Bearer {api_key}"}
82
response = requests.get(cls.BALANCE_ENDPOINT, headers=headers, timeout=timeout)
83
response.raise_for_status()
84
data = response.json()
85
cls.balance = float(data.get("balance", 0.0))
86
debug.log(f"Pollinations AI balance: {cls.balance:.2f} Pollen")
87
return cls.balance
88
except Exception as e:
89
debug.error(f"Failed to get balance:", e)
90
return None
74
91
75
92
@classmethod
76
93
def get_models(cls, api_key: Optional[str] = None, timeout: Optional[float] = None, **kwargs):
@@ -86,6 +103,14 @@ class PollinationsAI(AsyncGeneratorProvider, ProviderModelMixin):
86
103
87
104
if not api_key:
88
105
api_key = AuthManager.load_api_key(cls)
106
if not api_key or api_key.startswith("g4f_") or api_key.startswith("gfs_"):
107
api_key = "".join(cls.api_key)
108
109
if cls.balance or cls.balance is None and cls.get_balance(api_key, timeout) and cls.balance > 0:
110
debug.log(f"Authenticated with Pollinations AI using API key.")
111
else:
112
debug.log(f"Using Pollinations AI without authentication.")
113
api_key = None
89
114
90
115
if not cls._free_models_loaded or api_key and not cls._gen_models_loaded:
91
116
path = Path(get_cookies_dir()) / "models" / datetime.today().strftime('%Y-%m-%d') / f"{cls.__name__}{'-auth' if api_key else ''}.json"
@@ -194,36 +219,36 @@ class PollinationsAI(AsyncGeneratorProvider, ProviderModelMixin):
194
219
195
220
@classmethod
196
221
async def create_async_generator(
197
cls,
198
model: str,
199
messages: Messages,
200
stream: bool = True,
201
proxy: str = None,
202
cache: bool = None,
203
api_key: str = None,
204
extra_body: dict = None,
205
# Image generation parameters
206
prompt: str = None,
207
aspect_ratio: str = None,
208
width: int = None,
209
height: int = None,
210
seed: Optional[int] = None,
211
nologo: bool = True,
212
private: bool = False,
213
enhance: bool = None,
214
safe: bool = False,
215
transparent: bool = False,
216
n: int = 1,
217
# Text generation parameters
218
media: MediaListType = None,
219
temperature: float = None,
220
presence_penalty: float = None,
221
top_p: float = None,
222
frequency_penalty: float = None,
223
response_format: Optional[dict] = None,
224
extra_parameters: list[str] = ["tools", "parallel_tool_calls", "tool_choice", "reasoning_effort",
225
"logit_bias", "voice", "modalities", "audio"],
226
**kwargs
222
cls,
223
model: str,
224
messages: Messages,
225
stream: bool = True,
226
proxy: str = None,
227
cache: bool = None,
228
api_key: str = None,
229
extra_body: dict = None,
230
# Image generation parameters
231
prompt: str = None,
232
aspect_ratio: str = None,
233
width: int = None,
234
height: int = None,
235
seed: Optional[int] = None,
236
nologo: bool = True,
237
private: bool = False,
238
enhance: bool = None,
239
safe: bool = False,
240
transparent: bool = False,
241
n: int = 1,
242
# Text generation parameters
243
media: MediaListType = None,
244
temperature: float = None,
245
presence_penalty: float = None,
246
top_p: float = None,
247
frequency_penalty: float = None,
248
response_format: Optional[dict] = None,
249
extra_parameters: list[str] = ["tools", "parallel_tool_calls", "tool_choice", "reasoning_effort",
250
"logit_bias", "voice", "modalities", "audio"],
251
**kwargs
227
252
) -> AsyncResult:
228
253
if cache is None:
229
254
cache = kwargs.get("action") != "variant"
@@ -237,7 +262,7 @@ class PollinationsAI(AsyncGeneratorProvider, ProviderModelMixin):
237
262
has_audio = True
238
263
break
239
264
model = "openai-audio" if has_audio else cls.default_model
240
elif (cls._gen_models_loaded if api_key else cls._free_models_loaded) or cls.get_models(api_key=api_key, timeout=kwargs.get("timeout")):
265
if cls.get_models(api_key=api_key, timeout=kwargs.get("timeout")):
241
266
if model in cls.model_aliases:
242
267
model = cls.model_aliases[model]
243
268
debug.log(f"Using model: {model}")
@@ -353,7 +378,7 @@ class PollinationsAI(AsyncGeneratorProvider, ProviderModelMixin):
353
378
return f"{url}&seed={seed}" if seed else url
354
379
355
380
headers = None
356
if api_key:
381
if api_key and api_key.startswith("g4f_") or api_key.startswith("gfs_"):
357
382
headers = {"authorization": f"Bearer {api_key}"}
358
383
async with ClientSession(
359
384
headers=DEFAULT_HEADERS,
@@ -456,10 +481,12 @@ class PollinationsAI(AsyncGeneratorProvider, ProviderModelMixin):
456
481
**extra_body
457
482
)
458
483
headers = None
459
if api_key:
484
if api_key and not api_key.startswith("g4f_") and not api_key.startswith("gfs_"):
460
485
headers = {"authorization": f"Bearer {api_key}"}
486
elif cls.balance > 0:
487
headers = {"authorization": f"Bearer {"".join(cls.api_key)}"}
461
488
yield JsonRequest.from_dict(data)
462
if api_key and not api_key.startswith("g4f_") and not api_key.startswith("gfs_"):
489
if headers:
463
490
url = cls.gen_text_api_endpoint
464
491
else:
465
492
url = cls.text_api_endpoint
@@ -14,7 +14,6 @@ class Ollama(OpenaiTemplate):
14
14
label = "Ollama 🦙"
15
15
url = "https://ollama.com"
16
16
login_url = "https://ollama.com/settings/keys"
17
backup_url = "https://g4f.dev/api/ollama"
18
17
needs_auth = False
19
18
working = True
20
19
active_by_default = True
@@ -15,7 +15,6 @@ class Azure(OpenaiTemplate):
15
15
label = "Azure ☁️"
16
16
url = "https://ai.azure.com"
17
17
base_url = "https://g4f.dev/api/azure"
18
backup_url = "https://g4f.dev/api/azure"
19
18
working = True
20
19
active_by_default = False
21
20
login_url = "https://discord.gg/qXA4Wf4Fsm"
@@ -7,7 +7,6 @@ class Groq(OpenaiTemplate):
7
7
url = "https://console.groq.com/playground"
8
8
login_url = "https://console.groq.com/keys"
9
9
base_url = "https://api.groq.com/openai/v1"
10
backup_url = "https://g4f.dev/api/groq"
11
10
working = True
12
11
active_by_default = True
13
12
default_model = DEFAULT_MODEL
@@ -6,7 +6,6 @@ from ...config import DEFAULT_MODEL
6
6
class Nvidia(OpenaiTemplate):
7
7
label = "Nvidia"
8
8
base_url = "https://integrate.api.nvidia.com/v1"
9
backup_url = "https://g4f.dev/api/nvidia"
10
9
login_url = "https://google.com"
11
10
url = "https://build.nvidia.com"
12
11
working = True
@@ -13,7 +13,6 @@ class OpenRouter(OpenaiTemplate):
13
13
14
14
class OpenRouterFree(OpenRouter):
15
15
label = "OpenRouter (free)"
16
backup_url = "https://g4f.dev/api/openrouter"
17
16
max_tokens = 4096
18
17
active_by_default = True
19
18