-
-
Notifications
You must be signed in to change notification settings - Fork 364
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* fixing browser * fix syntax * try other container as base * use node 20 * use layers * fix chromium * add chromium sandbox and env vars * add chromium flags * clean up * revert to a previous version of g4f * use client * use asyncio * revert to previous version * switching retry method * use str * change defaults * more changes to default models * improve rotation * improve logic * select model * fix err * fix file path * fix defaults * improve logic * add logging, remove provider * skip if provider models is empty * remove provider
- Loading branch information
Showing
8 changed files
with
159 additions
and
46 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,39 +1,146 @@ | ||
from g4f.client import AsyncClient | ||
import logging | ||
import asyncio | ||
import random | ||
from g4f.Provider import ( | ||
HuggingChat, | ||
ChatgptAi, | ||
DeepInfra, | ||
ChatBase, | ||
Liaobots, | ||
FreeGpt, | ||
GptGo, | ||
Gpt6, | ||
) | ||
|
||
|
||
class Gpt4freeProvider: | ||
def __init__(self, AI_MODEL: str = "gemini-pro", **kwargs): | ||
self.requirements = ["g4f"] | ||
self.AI_MODEL = AI_MODEL if AI_MODEL else "gemini-pro" | ||
def __init__(self, AI_MODEL: str = "gpt-3.5-turbo", **kwargs): | ||
self.requirements = ["g4f"] # Breaking changes were made after g4f v0.2.6.2 | ||
self.AI_MODEL = AI_MODEL if AI_MODEL else "gpt-3.5-turbo" | ||
self.provider = ChatgptAi | ||
self.provider_name = "ChatgptAi" | ||
self.providers = [ | ||
{ | ||
"name": "HuggingChat", | ||
"class": HuggingChat, | ||
"models": [ | ||
"mistralai/Mixtral-8x7B-Instruct-v0.1", | ||
"mistralai/Mistral-7B-Instruct-v0.1", | ||
"openchat/openchat_3.5", | ||
"meta-llama/Llama-2-70b-chat-hf", | ||
], | ||
}, | ||
{ | ||
"name": "ChatgptAi", | ||
"class": ChatgptAi, | ||
"models": [ | ||
"gpt-3.5-turbo", | ||
], | ||
}, | ||
{ | ||
"name": "DeepInfra", | ||
"class": DeepInfra, | ||
"models": [ | ||
"meta-llama/Meta-Llama-3-70B-Instruct", | ||
"Qwen/Qwen2-72B-Instruct", | ||
], | ||
}, | ||
{ | ||
"name": "ChatBase", | ||
"class": ChatBase, | ||
"models": [ | ||
"gpt-3.5-turbo", | ||
], | ||
}, | ||
{ | ||
"name": "Liaobots", | ||
"class": Liaobots, | ||
"models": [ | ||
"gpt-4", | ||
], | ||
}, | ||
{ | ||
"name": "FreeGpt", | ||
"class": FreeGpt, | ||
"models": [ | ||
"gpt-3.5-turbo", | ||
], | ||
}, | ||
{ | ||
"name": "GptGo", | ||
"class": GptGo, | ||
"models": [ | ||
"gpt-3.5-turbo", | ||
], | ||
}, | ||
{ | ||
"name": "Gpt6", | ||
"class": Gpt6, | ||
"models": [ | ||
"gpt-3.5-turbo", | ||
], | ||
}, | ||
] | ||
self.failures = [] | ||
|
||
@staticmethod | ||
def services(): | ||
return ["llm"] | ||
|
||
async def inference(self, prompt, tokens: int = 0, images: list = []): | ||
asyncio.set_event_loop_policy(asyncio.DefaultEventLoopPolicy()) | ||
client = AsyncClient() | ||
models = ["gemini-pro", "gpt-4-turbo", "gpt-4", "mixtral-8x7b", "mistral-7b"] | ||
logging.info( | ||
f"[Gpt4Free] Using provider: {self.provider_name} with model: {self.AI_MODEL}" | ||
) | ||
try: | ||
response = await client.chat.completions.create( | ||
model=self.AI_MODEL, | ||
messages=[{"role": "user", "content": prompt}], | ||
stream=False, | ||
) | ||
return str(response.choices[0].message.content) | ||
except Exception as e: | ||
logging.warning(f"gpt4free API Error: {e}") | ||
for model in models: | ||
try: | ||
response = await client.chat.completions.create( | ||
model=model, | ||
return ( | ||
await asyncio.gather( | ||
self.provider.create_async( | ||
model=self.AI_MODEL, | ||
messages=[{"role": "user", "content": prompt}], | ||
stream=False, | ||
) | ||
return str(response.choices[0].message.content) | ||
except Exception as e: | ||
logging.warning(f"gpt4free API Error: {e}") | ||
continue | ||
return "Unable to retrieve a response from the gpt4free provider." | ||
) | ||
)[0] | ||
except Exception as e: | ||
logging.error(f"[Gpt4Free] {e}") | ||
self.failures.append( | ||
{"provider": self.provider_name, "model": self.AI_MODEL} | ||
) | ||
if len(self.failures) < len(self.providers): | ||
available_providers = self.get_available_providers() | ||
if available_providers: | ||
provider = random.choice(available_providers) | ||
self.provider = provider["class"] | ||
self.provider_name = provider["name"] | ||
self.AI_MODEL = random.choice(provider["models"]) | ||
logging.info( | ||
f"[Gpt4Free] Switching to provider: {self.provider_name} with model: {self.AI_MODEL}" | ||
) | ||
return await self.inference( | ||
prompt=prompt, tokens=tokens, images=images | ||
) | ||
else: | ||
return "No available providers. Unable to retrieve response." | ||
else: | ||
return "All providers exhausted. Unable to retrieve response." | ||
|
||
def get_available_providers(self): | ||
available_providers = [] | ||
for provider in self.providers: | ||
provider_models = provider["models"] | ||
if not isinstance(provider_models, list): | ||
provider_models = [provider_models] | ||
# Remove any models that have failed | ||
available_models = [ | ||
model | ||
for model in provider_models | ||
if not any( | ||
failure["provider"] == provider["name"] | ||
and failure["model"] == model | ||
for failure in self.failures | ||
) | ||
] | ||
if available_models: | ||
provider_copy = provider.copy() | ||
provider_copy["models"] = available_models | ||
available_providers.append(provider_copy) | ||
return available_providers |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters