diff options
-rw-r--r-- | README.md | 59 | ||||
-rw-r--r-- | docker/Dockerfile | 8 | ||||
-rw-r--r-- | g4f/Provider/Bing.py | 2 | ||||
-rw-r--r-- | g4f/Provider/BingCreateImages.py | 14 | ||||
-rw-r--r-- | g4f/Provider/HuggingChat.py | 3 | ||||
-rw-r--r-- | g4f/Provider/openai/har_file.py | 3 | ||||
-rw-r--r-- | g4f/gui/client/static/css/style.css | 18 | ||||
-rw-r--r-- | g4f/gui/client/static/js/chat.v1.js | 55 |
8 files changed, 106 insertions, 56 deletions
@@ -347,29 +347,29 @@ While we wait for gpt-5, here is a list of new models that are at least better t ### Other -| Website | Provider | GPT-3.5 | GPT-4 | Stream | Status | Auth | -| ------ | ------- | ------- | ----- | ------ | ------ | ---- | -| [openchat.team](https://openchat.team) | `g4f.Provider.Aura` | ❌ | ❌ | ✔️ | ![Unknown](https://img.shields.io/badge/Unknown-grey) | ❌ | -| [blackbox.ai](https://www.blackbox.ai) | `g4f.Provider.Blackbox` | ❌ | ❌ | ✔️ | ![Active](https://img.shields.io/badge/Active-brightgreen) | ❌ | -| [cohereforai-c4ai-command-r-plus.hf.space](https://cohereforai-c4ai-command-r-plus.hf.space) | `g4f.Provider.Cohere` | ❌ | ❌ | ✔️ | ![Unknown](https://img.shields.io/badge/Unknown-grey) | ❌ | -| [deepinfra.com](https://deepinfra.com) | `g4f.Provider.DeepInfra` | ❌ | ❌ | ✔️ | ![Active](https://img.shields.io/badge/Active-brightgreen) | ❌ | -| [free.chatgpt.org.uk](https://free.chatgpt.org.uk) | `g4f.Provider.FreeChatgpt` | ❌ | ❌ | ✔️ | ![Unknown](https://img.shields.io/badge/Unknown-grey) | ❌ | -| [gemini.google.com](https://gemini.google.com) | `g4f.Provider.Gemini` | ❌ | ❌ | ✔️ | ![Active](https://img.shields.io/badge/Active-brightgreen) | ✔️ | -| [ai.google.dev](https://ai.google.dev) | `g4f.Provider.GeminiPro` | ❌ | ❌ | ✔️ | ![Active](https://img.shields.io/badge/Active-brightgreen) | ✔️ | -| [gemini-chatbot-sigma.vercel.app](https://gemini-chatbot-sigma.vercel.app) | `g4f.Provider.GeminiProChat` | ❌ | ❌ | ✔️ | ![Unknown](https://img.shields.io/badge/Unknown-grey) | ❌ | -| [developers.sber.ru](https://developers.sber.ru/gigachat) | `g4f.Provider.GigaChat` | ❌ | ❌ | ✔️ | ![Unknown](https://img.shields.io/badge/Unknown-grey) | ✔️ | -| [console.groq.com](https://console.groq.com/playground) | `g4f.Provider.Groq` | ❌ | ❌ | ✔️ | ![Active](https://img.shields.io/badge/Active-brightgreen) | ✔️ | -| [huggingface.co](https://huggingface.co/chat) | `g4f.Provider.HuggingChat` | ❌ | ❌ | ✔️ | ![Active](https://img.shields.io/badge/Active-brightgreen) | ❌ | -| [huggingface.co](https://huggingface.co/chat) | `g4f.Provider.HuggingFace` | ❌ | ❌ | ✔️ | ![Active](https://img.shields.io/badge/Active-brightgreen) | ❌ | -| [llama2.ai](https://www.llama2.ai) | `g4f.Provider.Llama` | ❌ | ❌ | ✔️ | ![Unknown](https://img.shields.io/badge/Unknown-grey) | ❌ | -| [meta.ai](https://www.meta.ai) | `g4f.Provider.MetaAI` | ❌ | ❌ | ✔️ | ![Active](https://img.shields.io/badge/Active-brightgreen) | ❌+✔️ | -| [openrouter.ai](https://openrouter.ai) | `g4f.Provider.OpenRouter` | ❌ | ❌ | ✔️ | ![Active](https://img.shields.io/badge/Active-brightgreen) | ✔️ | -| [labs.perplexity.ai](https://labs.perplexity.ai) | `g4f.Provider.PerplexityLabs` | ❌ | ❌ | ✔️ | ![Active](https://img.shields.io/badge/Active-brightgreen) | ❌ | -| [pi.ai](https://pi.ai/talk) | `g4f.Provider.Pi` | ❌ | ❌ | ✔️ | ![Unknown](https://img.shields.io/badge/Unknown-grey) | ❌ | -| [replicate.com](https://replicate.com) | `g4f.Provider.ReplicateImage` | ❌ | ❌ | ✔️ | ![Unknown](https://img.shields.io/badge/Unknown-grey) | ❌ | -| [theb.ai](https://theb.ai) | `g4f.Provider.ThebApi` | ❌ | ❌ | ✔️ | ![Unknown](https://img.shields.io/badge/Unknown-grey) | ✔️ | -| [whiterabbitneo.com](https://www.whiterabbitneo.com) | `g4f.Provider.WhiteRabbitNeo` | ❌ | ❌ | ✔️ | ![Unknown](https://img.shields.io/badge/Unknown-grey) | ✔️ | -| [bard.google.com](https://bard.google.com) | `g4f.Provider.Bard` | ❌ | ❌ | ❌ | ![Inactive](https://img.shields.io/badge/Inactive-red) | ✔️ | +| Website | Provider | Stream | Status | Auth | +| ------ | ------- | ------ | ------ | ---- | +| [openchat.team](https://openchat.team) | `g4f.Provider.Aura`| ✔️ | ![Unknown](https://img.shields.io/badge/Unknown-grey) | ❌ | +| [blackbox.ai](https://www.blackbox.ai) | `g4f.Provider.Blackbox`| ✔️ | ![Active](https://img.shields.io/badge/Active-brightgreen) | ❌ | +| [cohereforai-c4ai-command-r-plus.hf.space](https://cohereforai-c4ai-command-r-plus.hf.space) | `g4f.Provider.Cohere`| ✔️ | ![Unknown](https://img.shields.io/badge/Unknown-grey) | ❌ | +| [deepinfra.com](https://deepinfra.com) | `g4f.Provider.DeepInfra`| ✔️ | ![Active](https://img.shields.io/badge/Active-brightgreen) | ❌ | +| [free.chatgpt.org.uk](https://free.chatgpt.org.uk) | `g4f.Provider.FreeChatgpt`| ✔️ | ![Unknown](https://img.shields.io/badge/Unknown-grey) | ❌ | +| [gemini.google.com](https://gemini.google.com) | `g4f.Provider.Gemini`| ✔️ | ![Active](https://img.shields.io/badge/Active-brightgreen) | ✔️ | +| [ai.google.dev](https://ai.google.dev) | `g4f.Provider.GeminiPro`| ✔️ | ![Active](https://img.shields.io/badge/Active-brightgreen) | ✔️ | +| [gemini-chatbot-sigma.vercel.app](https://gemini-chatbot-sigma.vercel.app) | `g4f.Provider.GeminiProChat`| ✔️ | ![Unknown](https://img.shields.io/badge/Unknown-grey) | ❌ | +| [developers.sber.ru](https://developers.sber.ru/gigachat) | `g4f.Provider.GigaChat`| ✔️ | ![Unknown](https://img.shields.io/badge/Unknown-grey) | ✔️ | +| [console.groq.com](https://console.groq.com/playground) | `g4f.Provider.Groq`| ✔️ | ![Active](https://img.shields.io/badge/Active-brightgreen) | ✔️ | +| [huggingface.co](https://huggingface.co/chat) | `g4f.Provider.HuggingChat`| ✔️ | ![Active](https://img.shields.io/badge/Active-brightgreen) | ❌ | +| [huggingface.co](https://huggingface.co/chat) | `g4f.Provider.HuggingFace`| ✔️ | ![Active](https://img.shields.io/badge/Active-brightgreen) | ❌ | +| [llama2.ai](https://www.llama2.ai) | `g4f.Provider.Llama`| ✔️ | ![Unknown](https://img.shields.io/badge/Unknown-grey) | ❌ | +| [meta.ai](https://www.meta.ai) | `g4f.Provider.MetaAI`| ✔️ | ![Active](https://img.shields.io/badge/Active-brightgreen) | ❌ | +| [openrouter.ai](https://openrouter.ai) | `g4f.Provider.OpenRouter`| ✔️ | ![Active](https://img.shields.io/badge/Active-brightgreen) | ✔️ | +| [labs.perplexity.ai](https://labs.perplexity.ai) | `g4f.Provider.PerplexityLabs`| ✔️ | ![Active](https://img.shields.io/badge/Active-brightgreen) | ❌ | +| [pi.ai](https://pi.ai/talk) | `g4f.Provider.Pi`| ✔️ | ![Unknown](https://img.shields.io/badge/Unknown-grey) | ❌ | +| [replicate.com](https://replicate.com) | `g4f.Provider.Replicate`| ✔️ | ![Unknown](https://img.shields.io/badge/Unknown-grey) | ❌ | +| [theb.ai](https://theb.ai) | `g4f.Provider.ThebApi`| ✔️ | ![Unknown](https://img.shields.io/badge/Unknown-grey) | ✔️ | +| [whiterabbitneo.com](https://www.whiterabbitneo.com) | `g4f.Provider.WhiteRabbitNeo`| ✔️ | ![Unknown](https://img.shields.io/badge/Unknown-grey) | ✔️ | +| [bard.google.com](https://bard.google.com) | `g4f.Provider.Bard`| ❌ | ![Inactive](https://img.shields.io/badge/Inactive-red) | ✔️ | ### Models @@ -405,13 +405,13 @@ While we wait for gpt-5, here is a list of new models that are at least better t | Label | Provider | Image Model | Vision Model | Website | | ----- | -------- | ----------- | ------------ | ------- | | Microsoft Copilot in Bing | `g4f.Provider.Bing` | dall-e-3 | gpt-4-vision | [bing.com](https://bing.com/chat) | -| DeepInfra | `g4f.Provider.DeepInfra` | stability-ai/sdxl| llava-1.5-7b-hf | [deepinfra.com](https://deepinfra.com) | -| Gemini | `g4f.Provider.Gemini` | gemini| gemini | [gemini.google.com](https://gemini.google.com) | -| Gemini API | `g4f.Provider.GeminiPro` | ❌| gemini-1.5-pro-latest | [ai.google.dev](https://ai.google.dev) | -| Meta AI | `g4f.Provider.MetaAI` | meta| ❌ | [meta.ai](https://www.meta.ai) | +| DeepInfra | `g4f.Provider.DeepInfra` | stability-ai/sdxl | llava-1.5-7b-hf | [deepinfra.com](https://deepinfra.com) | +| Gemini | `g4f.Provider.Gemini` | ✔️ | ✔️ | [gemini.google.com](https://gemini.google.com) | +| Gemini API | `g4f.Provider.GeminiPro` | ❌ | gemini-1.5-pro | [ai.google.dev](https://ai.google.dev) | +| Meta AI | `g4f.Provider.MetaAI` | ✔️ | ❌ | [meta.ai](https://www.meta.ai) | | OpenAI ChatGPT | `g4f.Provider.OpenaiChat` | dall-e-3 | gpt-4-vision | [chat.openai.com](https://chat.openai.com) | -| Replicate | `g4f.Provider.Replicate` | stability-ai/sdxl| ❌ | [replicate.com](https://replicate.com) | -| You.com | `g4f.Provider.You` | dall-e| agent | [you.com](https://you.com) | +| Replicate | `g4f.Provider.Replicate` | stability-ai/sdxl| llava-v1.6-34b | [replicate.com](https://replicate.com) | +| You.com | `g4f.Provider.You` | dall-e-3| ✔️ | [you.com](https://you.com) | ## 🔗 Powered by gpt4free @@ -875,7 +875,6 @@ A list of all contributors is available [here](https://github.com/xtekky/gpt4fre - The [`Gemini.py`](g4f/Provider/needs_auth/Gemini.py) has input from [dsdanielpark/Gemini-API](https://github.com/dsdanielpark/Gemini-API) - The [`MetaAI.py`](g4f/Provider/MetaAI.py) file contains code from [meta-ai-api](https://github.com/Strvm/meta-ai-api) by [@Strvm](https://github.com/Strvm) - *Having input implies that the AI's code generation utilized it as one of many sources.* ## ©️ Copyright diff --git a/docker/Dockerfile b/docker/Dockerfile index 041334a6..eb03390c 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -73,13 +73,11 @@ COPY requirements.txt $G4F_DIR # Upgrade pip for the latest features and install the project's Python dependencies. RUN pip install --break-system-packages --upgrade pip \ - && pip install --break-system-packages -r requirements.txt - -# Install selenium driver and uninstall webdriver -RUN pip install --break-system-packages \ + && pip install --break-system-packages -r requirements.txt \ + && pip install --break-system-packages \ undetected-chromedriver selenium-wire \ && pip uninstall -y --break-system-packages \ - webdriver plyer nodriver + pywebview plyer # Copy the entire package into the container. ADD --chown=$G4F_USER:$G4F_USER g4f $G4F_DIR/g4f diff --git a/g4f/Provider/Bing.py b/g4f/Provider/Bing.py index bfd74f8c..a9eb78e6 100644 --- a/g4f/Provider/Bing.py +++ b/g4f/Provider/Bing.py @@ -484,7 +484,7 @@ async def stream_generate( elif message.get('contentType') == "IMAGE": prompt = message.get('text') try: - image_client = BingCreateImages(cookies, proxy) + image_client = BingCreateImages(cookies, proxy, api_key) image_response = await image_client.create_async(prompt) except Exception as e: if debug.logging: diff --git a/g4f/Provider/BingCreateImages.py b/g4f/Provider/BingCreateImages.py index 69bf1e92..9e5146cc 100644 --- a/g4f/Provider/BingCreateImages.py +++ b/g4f/Provider/BingCreateImages.py @@ -19,9 +19,13 @@ class BingCreateImages(AsyncGeneratorProvider, ProviderModelMixin): needs_auth = True image_models = ["dall-e"] - def __init__(self, cookies: Cookies = None, proxy: str = None) -> None: - self.cookies: Cookies = cookies - self.proxy: str = proxy + def __init__(self, cookies: Cookies = None, proxy: str = None, api_key: str = None) -> None: + if api_key is not None: + if cookies is None: + cookies = {} + cookies["_U"] = api_key + self.cookies = cookies + self.proxy = proxy @classmethod async def create_async_generator( @@ -33,9 +37,7 @@ class BingCreateImages(AsyncGeneratorProvider, ProviderModelMixin): proxy: str = None, **kwargs ) -> AsyncResult: - if api_key is not None: - cookies = {"_U": api_key} - session = BingCreateImages(cookies, proxy) + session = BingCreateImages(cookies, proxy, api_key) yield await session.create_async(messages[-1]["content"]) def create(self, prompt: str) -> Iterator[Union[ImageResponse, str]]: diff --git a/g4f/Provider/HuggingChat.py b/g4f/Provider/HuggingChat.py index 527f0a56..65273345 100644 --- a/g4f/Provider/HuggingChat.py +++ b/g4f/Provider/HuggingChat.py @@ -24,6 +24,9 @@ class HuggingChat(AsyncGeneratorProvider, ProviderModelMixin): 'mistralai/Mistral-7B-Instruct-v0.2', 'meta-llama/Meta-Llama-3-70B-Instruct' ] + model_aliases = { + "mistralai/Mistral-7B-Instruct-v0.1": "mistralai/Mistral-7B-Instruct-v0.2" + } @classmethod def get_models(cls): diff --git a/g4f/Provider/openai/har_file.py b/g4f/Provider/openai/har_file.py index da25b637..6a34c97a 100644 --- a/g4f/Provider/openai/har_file.py +++ b/g4f/Provider/openai/har_file.py @@ -30,6 +30,7 @@ sessionUrl = "https://chat.openai.com/api/auth/session" chatArk: arkReq = None accessToken: str = None cookies: dict = None +headers: dict = None def readHAR(): dirPath = "./" @@ -130,7 +131,7 @@ def getN() -> str: return base64.b64encode(timestamp.encode()).decode() async def getArkoseAndAccessToken(proxy: str) -> tuple[str, str, dict, dict]: - global chatArk, accessToken, cookies + global chatArk, accessToken, cookies, headers if chatArk is None or accessToken is None: chatArk, accessToken, cookies, headers = readHAR() if chatArk is None: diff --git a/g4f/gui/client/static/css/style.css b/g4f/gui/client/static/css/style.css index a28c9cd6..979f9f96 100644 --- a/g4f/gui/client/static/css/style.css +++ b/g4f/gui/client/static/css/style.css @@ -210,7 +210,9 @@ body { .conversations .convo .fa-ellipsis-vertical { position: absolute; - right: 14px; + right: 8px; + width: 14px; + text-align: center; } .conversations .convo .choise { @@ -224,6 +226,10 @@ body { cursor: pointer; } +.bottom_buttons i { + width: 14px; +} + .convo-title { color: var(--colour-3); font-size: 14px; @@ -232,9 +238,17 @@ body { overflow: hidden; white-space: nowrap; margin-right: 10px; + background-color: transparent; + border: 0; + width: 100%; +} + +.convo-title:focus { + outline: 1px solid var(--colour-3) !important; } -.convo-title .datetime { +.convo .datetime { + white-space: nowrap; font-size: 10px; } diff --git a/g4f/gui/client/static/js/chat.v1.js b/g4f/gui/client/static/js/chat.v1.js index 8b00eed2..d5988c26 100644 --- a/g4f/gui/client/static/js/chat.v1.js +++ b/g4f/gui/client/static/js/chat.v1.js @@ -482,12 +482,35 @@ const clear_conversation = async () => { } }; +async function set_conversation_title(conversation_id, title) { + conversation = await get_conversation(conversation_id) + conversation.new_title = title; + appStorage.setItem( + `conversation:${conversation.id}`, + JSON.stringify(conversation) + ); +} + const show_option = async (conversation_id) => { const conv = document.getElementById(`conv-${conversation_id}`); const choi = document.getElementById(`cho-${conversation_id}`); conv.style.display = "none"; choi.style.display = "block"; + + const el = document.getElementById(`convo-${conversation_id}`); + const trash_el = el.querySelector(".fa-trash"); + const title_el = el.querySelector("span.convo-title"); + if (title_el) { + const left_el = el.querySelector(".left"); + const input_el = document.createElement("input"); + input_el.value = title_el.innerText; + input_el.classList.add("convo-title"); + input_el.onfocus = () => trash_el.style.display = "none"; + input_el.onchange = () => set_conversation_title(conversation_id, input_el.value); + left_el.removeChild(title_el); + left_el.appendChild(input_el); + } }; const hide_option = async (conversation_id) => { @@ -496,6 +519,18 @@ const hide_option = async (conversation_id) => { conv.style.display = "block"; choi.style.display = "none"; + + const el = document.getElementById(`convo-${conversation_id}`); + el.querySelector(".fa-trash").style.display = ""; + const input_el = el.querySelector("input.convo-title"); + if (input_el) { + const left_el = el.querySelector(".left"); + const span_el = document.createElement("span"); + span_el.innerText = input_el.value; + span_el.classList.add("convo-title"); + left_el.removeChild(input_el); + left_el.appendChild(span_el); + } }; const delete_conversation = async (conversation_id) => { @@ -709,18 +744,15 @@ const load_conversations = async () => { let html = ""; conversations.forEach((conversation) => { - if (conversation?.items.length > 0) { - let old_value = conversation.title; + if (conversation?.items.length > 0 && !conversation.new_title) { let new_value = (conversation.items[0]["content"]).trim(); let new_lenght = new_value.indexOf("\n"); new_lenght = new_lenght > 200 || new_lenght < 0 ? 200 : new_lenght; - conversation.title = new_value.substring(0, new_lenght); - if (conversation.title != old_value) { - appStorage.setItem( - `conversation:${conversation.id}`, - JSON.stringify(conversation) - ); - } + conversation.new_title = new_value.substring(0, new_lenght); + appStorage.setItem( + `conversation:${conversation.id}`, + JSON.stringify(conversation) + ); } let updated = ""; if (conversation.updated) { @@ -730,9 +762,10 @@ const load_conversations = async () => { } html += ` <div class="convo" id="convo-${conversation.id}"> - <div class="left" onclick="set_conversation('${conversation.id}')"> + <div class="left"> <i class="fa-regular fa-comments"></i> - <span class="convo-title"><span class="datetime">${updated}</span> ${conversation.title}</span> + <span class="datetime" onclick="set_conversation('${conversation.id}')">${updated}</span> + <span class="convo-title" onclick="set_conversation('${conversation.id}')">${conversation.new_title}</span> </div> <i onclick="show_option('${conversation.id}')" class="fa-solid fa-ellipsis-vertical" id="conv-${conversation.id}"></i> <div id="cho-${conversation.id}" class="choise" style="display:none;"> |