返回提交历史
Modified
g4f/Provider/PollinationsAI.py
+10
-19
Modified
g4f/Provider/needs_auth/PuterJS.py
+13
-0
Modified
g4f/providers/base_provider.py
+7
-4
XFEstudio/gpt4free
Refactor PollinationsAI and PuterJS for improved model handling and add quota retrieval; enhance error messaging in base_provider
35c548be
代码差异
3 个文件
+30
-23
@@ -50,13 +50,13 @@ class PollinationsAI(AsyncGeneratorProvider, ProviderModelMixin):
50
50
worker_models_endpoint = "https://g4f.space/api/pollinations/models"
51
51
52
52
# Models configuration
53
default_model = "openai"
53
default_model = "openai-fast"
54
54
fallback_model = "deepseek"
55
55
default_image_model = "flux"
56
56
default_vision_model = default_model
57
57
default_voice = "alloy"
58
58
text_models = {default_model: {"id": default_model}}
59
image_models = [default_image_model, "turbo", "kontext"]
59
image_models = {default_image_model: {"id": default_image_model}, "turbo": {"id": "turbo"}, "kontext": {"id": "kontext"}}
60
60
audio_models = {}
61
61
vision_models = [default_vision_model]
62
62
model_aliases = {
@@ -145,25 +145,17 @@ class PollinationsAI(AsyncGeneratorProvider, ProviderModelMixin):
145
145
else:
146
146
new_image_models = []
147
147
148
# Combine image models without duplicates
149
image_models = cls.image_models.copy() # Start with default model
150
151
# Add extra image models if not already in the list
148
# Add image and video models
149
cls.vision_models = []
150
cls.video_models = [model.get("name") for model in new_image_models if "video" in model.get("output_modalities", [])]
152
151
for model in new_image_models:
153
alias = get_alias(model)
154
model["label"] = alias
155
if model not in image_models:
156
if "image" in model.get("output_modalities", []):
157
if model.get("name") not in image_models:
158
image_models.append(model.get("name"))
159
if alias not in image_models:
160
image_models.append(alias)
152
if model.get("name") not in cls.video_models:
153
cls.image_models[model.get("name")] = {"id": model.get("name"), "label": get_alias(model), **model}
154
if "image" in model.get("input_modalities", []):
155
cls.vision_models.append(model.get("name"))
161
156
for alias in model.get("aliases", []):
162
157
cls.model_aliases[alias] = model.get("name")
163
158
164
cls.image_models = image_models
165
cls.video_models = [model.get("name") if isinstance(model, dict) else model for model in new_image_models if isinstance(model, dict) and "video" in model.get("output_modalities", [])]
166
cls.video_models = [get_alias(model) for model in cls.video_models if get_alias(model) != model]
167
159
text_response = requests.get(cls.text_models_endpoint, timeout=timeout)
168
160
if not text_response.ok:
169
161
text_response = requests.get(cls.text_models_endpoint, timeout=timeout)
@@ -180,8 +172,7 @@ class PollinationsAI(AsyncGeneratorProvider, ProviderModelMixin):
180
172
if model in cls.audio_models and alias not in cls.audio_models:
181
173
cls.audio_models.update({alias: {}})
182
174
183
cls.vision_models = [model.get("name") for model in models if "image" in model.get("input_modalities", [])]
184
cls.vision_models.extend([get_alias(model) for model in cls.vision_models if get_alias(model) != model])
175
cls.vision_models.extend([model.get("name") for model in models if "image" in model.get("input_modalities", [])])
185
176
for model in models:
186
177
for alias in model.get("aliases", []):
187
178
cls.model_aliases[alias] = model.get("name")
@@ -226,6 +226,19 @@ class PuterJS(AsyncGeneratorProvider, ProviderModelMixin):
226
226
cls.vision_models.append(model)
227
227
return cls.models
228
228
229
@classmethod
230
async def get_quota(cls, api_key: Optional[str] = None, **kwargs) -> dict:
231
"""Get the quota information for the API key."""
232
if not api_key:
233
raise MissingAuthError("API key is required for Puter.js API")
234
url = "https://api.puter.com/metering/usage"
235
headers = {
236
"authorization": f"Bearer {api_key}"
237
}
238
response = requests.get(url, headers=headers)
239
response.raise_for_status()
240
return response.json()
241
229
242
@staticmethod
230
243
def get_driver_for_model(model: str) -> str:
231
244
"""Determine the appropriate driver based on the model name."""
@@ -122,8 +122,8 @@ class AbstractProvider(BaseProvider):
122
122
try:
123
123
return await asyncio.wait_for(
124
124
loop.run_in_executor(executor, create_func), timeout=timeout)
125
except TimeoutError:
126
raise
125
except TimeoutError as e:
126
raise TimeoutError("The operation timed out after {} seconds".format(timeout)) from e
127
127
128
128
@classmethod
129
129
def create_function(cls, *args, **kwargs) -> CreateResult:
@@ -350,12 +350,15 @@ class AsyncGeneratorProvider(AbstractProvider):
350
350
"""
351
351
response = cls.create_async_generator(*args, **kwargs)
352
352
if "stream_timeout" in kwargs or "timeout" in kwargs:
353
timeout = kwargs.get("stream_timeout") if cls.use_stream_timeout else kwargs.get("timeout")
353
354
while True:
354
355
try:
355
yield await await_callback(
356
yield await asyncio.wait_for(
356
357
response.__anext__(),
357
timeout=kwargs.get("stream_timeout") if cls.use_stream_timeout else kwargs.get("timeout")
358
timeout=timeout
358
359
)
360
except TimeoutError as e:
361
raise TimeoutError("The operation timed out after {} seconds".format(timeout)) from e
359
362
except StopAsyncIteration:
360
363
break
361
364
else: