mirror of
https://github.com/xtekky/gpt4free.git
synced 2025-12-06 02:30:41 -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:
parent
0c0c72c203
commit
0a070bdf10
24 changed files with 669 additions and 341 deletions
|
|
@ -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:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue