mirror of
https://github.com/xtekky/gpt4free.git
synced 2025-10-05 00:12:44 +08:00
feat: introduce AnyProvider & LM Arena, overhaul model/provider logic (#2925)
* feat: introduce AnyProvider & LM Arena, overhaul model/provider logic - **Provider additions & removals** - Added `Provider/LMArenaProvider.py` with full async stream implementation and vision model support - Registered `LMArenaProvider` in `Provider/__init__.py`; removed old `hf_space/LMArenaProvider.py` - Created `providers/any_provider.py`; registers `AnyProvider` dynamically in `Provider` - **Provider framework enhancements** - `providers/base_provider.py` - Added `video_models` and `audio_models` attributes - `providers/retry_provider.py` - Introduced `is_content()` helper; now treats `AudioResponse` as stream content - **Cloudflare provider refactor** - `Provider/Cloudflare.py` - Re‑implemented `get_models()` with `read_models()` helper, `fallback_models`, robust nodriver/curl handling and model‑name cleaning - **Other provider tweaks** - `Provider/Copilot.py` – removed `"reasoning"` alias and initial `setOptions` WS message - `Provider/PollinationsAI.py` & `PollinationsImage.py` - Converted `audio_models` from list to dict, adjusted usage checks and labels - `Provider/hf/__init__.py` – applies `model_aliases` remap before dispatch - `Provider/hf_space/DeepseekAI_JanusPro7b.py` – now merges media before upload - `needs_auth/Gemini.py` – dropped obsolete Gemini model entries - `needs_auth/GigaChat.py` – added lowercase `"gigachat"` alias - **API & client updates** - Replaced `ProviderUtils` with new `Provider` map usage throughout API and GUI server - Integrated `AnyProvider` as default fallback in `g4f/client` sync & async flows - API endpoints now return counts of providers per model and filter by `x_ignored` header - **GUI improvements** - Updated JS labels with emoji icons, provider ignore logic, model count display - **Model registry** - Renamed base model `"GigaChat:latest"` ➜ `"gigachat"` in `models.py` - **Miscellaneous** - Added audio/video flags to GUI provider list - Tightened error propagation in `retry_provider.raise_exceptions` * Fix unittests * fix: handle None conversation when accessing provider-specific data - Modified `AnyProvider` class in `g4f/providers/any_provider.py` - Updated logic to check if `conversation` is not None before accessing `provider.__name__` attribute - Wrapped `getattr(conversation, provider.__name__, None)` block in an additional `if conversation is not None` condition - Changed `setattr(conversation, provider.__name__, chunk)` to use `chunk.get_dict()` instead of the object directly - Ensured consistent use of `JsonConversation` when modifying or assigning `conversation` data * ``` feat: add provider string conversion & update IterListProvider call - In g4f/client/__init__.py, within both Completions and AsyncCompletions, added a check to convert the provider from a string using convert_to_provider(provider) when applicable. - In g4f/providers/any_provider.py, removed the second argument (False) from the IterListProvider constructor call in the async for loop. ``` --------- Co-authored-by: hlohaus <983577+hlohaus@users.noreply.github.com>
This commit is contained in:
@@ -10,7 +10,7 @@ from inspect import signature
|
||||
from ...errors import VersionNotFoundError, MissingAuthError
|
||||
from ...image.copy_images import copy_media, ensure_images_dir, images_dir
|
||||
from ...tools.run_tools import iter_run_tools
|
||||
from ...Provider import ProviderUtils, __providers__
|
||||
from ... import Provider
|
||||
from ...providers.base_provider import ProviderModelMixin
|
||||
from ...providers.retry_provider import BaseRetryProvider
|
||||
from ...providers.helper import format_image_prompt
|
||||
@@ -41,12 +41,14 @@ class Api:
|
||||
for model, providers in models.__models__.values()]
|
||||
|
||||
@staticmethod
|
||||
def get_provider_models(provider: str, api_key: str = None, api_base: str = None):
|
||||
if provider in ProviderUtils.convert:
|
||||
provider = ProviderUtils.convert[provider]
|
||||
def get_provider_models(provider: str, api_key: str = None, api_base: str = None, ignored: list = None):
|
||||
if provider in Provider.__map__:
|
||||
provider = Provider.__map__[provider]
|
||||
if issubclass(provider, ProviderModelMixin):
|
||||
if "api_key" in signature(provider.get_models).parameters:
|
||||
models = provider.get_models(api_key=api_key, api_base=api_base)
|
||||
elif "ignored" in signature(provider.get_models).parameters:
|
||||
models = provider.get_models(ignored=ignored)
|
||||
else:
|
||||
models = provider.get_models()
|
||||
return [
|
||||
@@ -57,7 +59,7 @@ class Api:
|
||||
"audio": getattr(provider, "default_audio_model", None) == model or model in getattr(provider, "audio_models", []),
|
||||
"video": getattr(provider, "default_video_model", None) == model or model in getattr(provider, "video_models", []),
|
||||
"image": False if provider.image_models is None else model in provider.image_models,
|
||||
"task": None if not hasattr(provider, "task_mapping") else provider.task_mapping[model] if model in provider.task_mapping else None
|
||||
"count": getattr(provider, "models_count", {}).get(model),
|
||||
}
|
||||
for model in models
|
||||
]
|
||||
@@ -69,15 +71,15 @@ class Api:
|
||||
"name": provider.__name__,
|
||||
"label": provider.label if hasattr(provider, "label") else provider.__name__,
|
||||
"parent": getattr(provider, "parent", None),
|
||||
"image": bool(getattr(provider, "image_models", False)),
|
||||
"audio": getattr(provider, "audio_models", None) is not None,
|
||||
"video": getattr(provider, "video_models", None) is not None,
|
||||
"image": len(getattr(provider, "image_models", [])),
|
||||
"audio": len(getattr(provider, "audio_models", [])),
|
||||
"video": len(getattr(provider, "video_models", [])),
|
||||
"vision": getattr(provider, "default_vision_model", None) is not None,
|
||||
"nodriver": getattr(provider, "use_nodriver", False),
|
||||
"hf_space": getattr(provider, "hf_space", False),
|
||||
"auth": provider.needs_auth,
|
||||
"login_url": getattr(provider, "login_url", None),
|
||||
} for provider in __providers__ if provider.working]
|
||||
} for provider in Provider.__providers__ if provider.working]
|
||||
|
||||
@staticmethod
|
||||
def get_version() -> dict:
|
||||
|
Reference in New Issue
Block a user