返回提交历史
Modified
g4f/Provider/template/OpenaiTemplate.py
+2
-0
Modified
g4f/gui/server/api.py
+1
-0
Modified
g4f/providers/retry_provider.py
+4
-0
Modified
g4f/providers/types.py
+1
-0
Modified
g4f/tools/run_tools.py
+47
-37
XFEstudio/gpt4free
Track live provider instances and update count on success or failure in various providers
1cbf9dfb
代码差异
5 个文件
+55
-37
@@ -49,6 +49,8 @@ class OpenaiTemplate(AsyncGeneratorProvider, ProviderModelMixin, RaiseErrorMixin
49
49
raise_for_status(response)
50
50
data = response.json()
51
51
data = data.get("data") if isinstance(data, dict) else data
52
if data:
53
cls.live += 1
52
54
cls.image_models = [model.get("name") if cls.use_model_names else model.get("id", model.get("name")) for model in data if model.get("image") or model.get("type") == "image" or model.get("supports_images")]
53
55
cls.vision_models = cls.vision_models.copy()
54
56
cls.vision_models += [model.get("name") if cls.use_model_names else model.get("id", model.get("name")) for model in data if model.get("vision")]
@@ -108,6 +108,7 @@ class Api:
108
108
"active_by_default": False if provider.active_by_default is None else provider.active_by_default,
109
109
"auth": provider.needs_auth,
110
110
"login_url": getattr(provider, "login_url", None),
111
"live": provider.live
111
112
} for provider in Provider.__providers__ if provider.working and safe_get_models(provider)]
112
113
113
114
def get_all_models(self) -> dict[str, list]:
@@ -99,9 +99,11 @@ class RotatedProvider(BaseRetryProvider):
99
99
if is_content(chunk):
100
100
started = True
101
101
if started:
102
provider.live += 1
102
103
# Success, so we return and do not rotate
103
104
return
104
105
except Exception as e:
106
provider.live -= 1
105
107
exceptions[provider.__name__] = e
106
108
debug.error(f"{provider.__name__} failed: {e}")
107
109
@@ -161,8 +163,10 @@ class RotatedProvider(BaseRetryProvider):
161
163
if is_content(chunk):
162
164
started = True
163
165
if started:
166
provider.live += 1
164
167
return # Success
165
168
except Exception as e:
169
provider.live -= 1
166
170
exceptions[provider.__name__] = e
167
171
debug.error(f"{provider.__name__} failed: {e}")
168
172
@@ -28,6 +28,7 @@ class BaseProvider(ABC):
28
28
params: str
29
29
create_function: callable
30
30
async_create_function: callable
31
live: int = 0
31
32
32
33
@classmethod
33
34
def get_dict(cls) -> Dict[str, str]:
@@ -253,18 +253,23 @@ async def async_iter_run_tools(
253
253
# Generate response
254
254
response = to_async_iterator(provider.async_create_function(model=model, messages=messages, **kwargs))
255
255
256
model_info = model
257
async for chunk in response:
258
if isinstance(chunk, ProviderInfo):
259
model_info = getattr(chunk, 'model', model_info)
260
elif isinstance(chunk, Usage):
261
usage = {"user": kwargs.get("user"), "model": model_info, "provider": provider.get_parent(), **chunk.get_dict()}
262
usage_dir = Path(get_cookies_dir()) / ".usage"
263
usage_file = usage_dir / f"{datetime.date.today()}.jsonl"
264
usage_dir.mkdir(parents=True, exist_ok=True)
265
with usage_file.open("a" if usage_file.exists() else "w") as f:
266
f.write(f"{json.dumps(usage)}\n")
267
yield chunk
256
try:
257
model_info = model
258
async for chunk in response:
259
if isinstance(chunk, ProviderInfo):
260
model_info = getattr(chunk, 'model', model_info)
261
elif isinstance(chunk, Usage):
262
usage = {"user": kwargs.get("user"), "model": model_info, "provider": provider.get_parent(), **chunk.get_dict()}
263
usage_dir = Path(get_cookies_dir()) / ".usage"
264
usage_file = usage_dir / f"{datetime.date.today()}.jsonl"
265
usage_dir.mkdir(parents=True, exist_ok=True)
266
with usage_file.open("a" if usage_file.exists() else "w") as f:
267
f.write(f"{json.dumps(usage)}\n")
268
yield chunk
269
provider.live += 1
270
except:
271
provider.live -= 1
272
raise
268
273
269
274
# Yield sources if available
270
275
if sources:
@@ -338,33 +343,38 @@ def iter_run_tools(
338
343
thinking_start_time = 0
339
344
processor = ThinkingProcessor()
340
345
model_info = model
341
for chunk in provider.create_function(model=model, messages=messages, provider=provider, **kwargs):
342
if isinstance(chunk, FinishReason):
343
if sources is not None:
344
yield sources
346
try:
347
for chunk in provider.create_function(model=model, messages=messages, provider=provider, **kwargs):
348
if isinstance(chunk, FinishReason):
349
if sources is not None:
350
yield sources
351
sources = None
352
yield chunk
353
continue
354
elif isinstance(chunk, Sources):
345
355
sources = None
346
yield chunk
347
continue
348
elif isinstance(chunk, Sources):
349
sources = None
350
elif isinstance(chunk, ProviderInfo):
351
model_info = getattr(chunk, 'model', model_info)
352
elif isinstance(chunk, Usage):
353
usage = {"user": kwargs.get("user"), "model": model_info, "provider": provider.get_parent(), **chunk.get_dict()}
354
usage_dir = Path(get_cookies_dir()) / ".usage"
355
usage_file = usage_dir / f"{datetime.date.today()}.jsonl"
356
usage_dir.mkdir(parents=True, exist_ok=True)
357
with usage_file.open("a" if usage_file.exists() else "w") as f:
358
f.write(f"{json.dumps(usage)}\n")
359
360
if not isinstance(chunk, str):
361
yield chunk
362
continue
356
elif isinstance(chunk, ProviderInfo):
357
model_info = getattr(chunk, 'model', model_info)
358
elif isinstance(chunk, Usage):
359
usage = {"user": kwargs.get("user"), "model": model_info, "provider": provider.get_parent(), **chunk.get_dict()}
360
usage_dir = Path(get_cookies_dir()) / ".usage"
361
usage_file = usage_dir / f"{datetime.date.today()}.jsonl"
362
usage_dir.mkdir(parents=True, exist_ok=True)
363
with usage_file.open("a" if usage_file.exists() else "w") as f:
364
f.write(f"{json.dumps(usage)}\n")
365
if not isinstance(chunk, str):
366
yield chunk
367
continue
368
369
thinking_start_time, results = processor.process_thinking_chunk(chunk, thinking_start_time)
363
370
364
thinking_start_time, results = processor.process_thinking_chunk(chunk, thinking_start_time)
365
366
for result in results:
367
yield result
371
for result in results:
372
yield result
373
374
provider.live += 1
375
except:
376
provider.live -= 1
377
raise
368
378
369
379
if sources is not None:
370
380
yield sources