diff options
author | Tekky <98614666+xtekky@users.noreply.github.com> | 2023-12-13 15:27:55 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-12-13 15:27:55 +0100 |
commit | 99127111f525d4ed1469c3547bcb491a8cdf5963 (patch) | |
tree | 10ed7693fe0116fa91ab9c77cbc0aa0951417f75 /g4f | |
parent | ~ (diff) | |
parent | Change default port for gui (diff) | |
download | gpt4free-99127111f525d4ed1469c3547bcb491a8cdf5963.tar gpt4free-99127111f525d4ed1469c3547bcb491a8cdf5963.tar.gz gpt4free-99127111f525d4ed1469c3547bcb491a8cdf5963.tar.bz2 gpt4free-99127111f525d4ed1469c3547bcb491a8cdf5963.tar.lz gpt4free-99127111f525d4ed1469c3547bcb491a8cdf5963.tar.xz gpt4free-99127111f525d4ed1469c3547bcb491a8cdf5963.tar.zst gpt4free-99127111f525d4ed1469c3547bcb491a8cdf5963.zip |
Diffstat (limited to '')
-rw-r--r-- | g4f/Provider/retry_provider.py | 7 | ||||
-rw-r--r-- | g4f/__init__.py | 81 | ||||
-rw-r--r-- | g4f/cli.py | 2 | ||||
-rw-r--r-- | g4f/debug.py | 39 | ||||
-rw-r--r-- | g4f/errors.py | 26 | ||||
-rw-r--r-- | g4f/gui/client/css/style.css | 18 | ||||
-rw-r--r-- | g4f/gui/client/html/index.html | 6 | ||||
-rw-r--r-- | g4f/gui/client/js/chat.v1.js | 239 | ||||
-rw-r--r-- | g4f/gui/run.py | 2 | ||||
-rw-r--r-- | g4f/gui/server/backend.py | 70 |
10 files changed, 252 insertions, 238 deletions
diff --git a/g4f/Provider/retry_provider.py b/g4f/Provider/retry_provider.py index 6fdefe0f..e49b6da6 100644 --- a/g4f/Provider/retry_provider.py +++ b/g4f/Provider/retry_provider.py @@ -6,6 +6,7 @@ from typing import List, Type, Dict from ..typing import CreateResult, Messages from .base_provider import BaseProvider, AsyncProvider from .. import debug +from ..errors import RetryProviderError, RetryNoProviderError class RetryProvider(AsyncProvider): @@ -84,8 +85,8 @@ class RetryProvider(AsyncProvider): def raise_exceptions(self) -> None: if self.exceptions: - raise RuntimeError("\n".join(["RetryProvider failed:"] + [ - f"{p}: {self.exceptions[p].__class__.__name__}: {self.exceptions[p]}" for p in self.exceptions + raise RetryProviderError("RetryProvider failed:\n" + "\n".join([ + f"{p}: {exception.__class__.__name__}: {exception}" for p, exception in self.exceptions.items() ])) - raise RuntimeError("RetryProvider: No provider found")
\ No newline at end of file + raise RetryNoProviderError("No provider found")
\ No newline at end of file diff --git a/g4f/__init__.py b/g4f/__init__.py index 92bce194..3b0fcad0 100644 --- a/g4f/__init__.py +++ b/g4f/__init__.py @@ -1,61 +1,35 @@ from __future__ import annotations import os -from requests import get -from importlib.metadata import version as get_package_version, PackageNotFoundError -from subprocess import check_output, CalledProcessError, PIPE +from .errors import * from .models import Model, ModelUtils, _all_models -from .Provider import BaseProvider, AsyncGeneratorProvider, RetryProvider +from .Provider import BaseProvider, AsyncGeneratorProvider, RetryProvider, ProviderUtils from .typing import Messages, CreateResult, AsyncResult, Union, List from . import debug -def get_version() -> str: - # Read from package manager - try: - return get_package_version("g4f") - except PackageNotFoundError: - pass - # Read from docker environment - current_version = os.environ.get("G4F_VERSION") - if current_version: - return current_version - # Read from git repository - try: - command = ["git", "describe", "--tags", "--abbrev=0"] - return check_output(command, text=True, stderr=PIPE).strip() - except CalledProcessError: - pass - -def get_lastet_version() -> str: - response = get("https://pypi.org/pypi/g4f/json").json() - return response["info"]["version"] - -def check_pypi_version() -> None: - try: - version = get_version() - latest_version = get_lastet_version() - except Exception as e: - print(f'Failed to check g4f pypi version: {e}') - if version != latest_version: - print(f'New pypi version: {latest_version} (current: {version}) | pip install -U g4f') - def get_model_and_provider(model : Union[Model, str], - provider : Union[type[BaseProvider], None], + provider : Union[type[BaseProvider], str, None], stream : bool, ignored : List[str] = None, ignore_working: bool = False, ignore_stream: bool = False) -> tuple[Model, type[BaseProvider]]: if debug.version_check: - check_pypi_version() debug.version_check = False - + debug.check_pypi_version() + + if isinstance(provider, str): + if provider in ProviderUtils.convert: + provider = ProviderUtils.convert[provider] + else: + raise ProviderNotFoundError(f'Provider not found: {provider}') + if isinstance(model, str): if model in ModelUtils.convert: model = ModelUtils.convert[model] else: - raise ValueError(f'The model: {model} does not exist') - + raise ModelNotFoundError(f'The model: {model} does not exist') + if not provider: provider = model.best_provider @@ -63,14 +37,14 @@ def get_model_and_provider(model : Union[Model, str], provider.providers = [p for p in provider.providers if p.__name__ not in ignored] if not provider: - raise RuntimeError(f'No provider found for model: {model}') - + raise ProviderNotFoundError(f'No provider found for model: {model}') + if not provider.working and not ignore_working: - raise RuntimeError(f'{provider.__name__} is not working') - + raise ProviderNotWorkingError(f'{provider.__name__} is not working') + if not ignore_stream and not provider.supports_stream and stream: - raise ValueError(f'{provider.__name__} does not support "stream" argument') - + raise StreamNotSupportedError(f'{provider.__name__} does not support "stream" argument') + if debug.logging: print(f'Using {provider.__name__} provider') @@ -80,7 +54,7 @@ class ChatCompletion: @staticmethod def create(model : Union[Model, str], messages : Messages, - provider : Union[type[BaseProvider], None] = None, + provider : Union[type[BaseProvider], str, None] = None, stream : bool = False, auth : Union[str, None] = None, ignored : List[str] = None, @@ -91,11 +65,15 @@ class ChatCompletion: model, provider = get_model_and_provider(model, provider, stream, ignored, ignore_working, ignore_stream_and_auth) if not ignore_stream_and_auth and provider.needs_auth and not auth: - raise ValueError( - f'{provider.__name__} requires authentication (use auth=\'cookie or token or jwt ...\' param)') + raise AuthenticationRequiredError(f'{provider.__name__} requires authentication (use auth=\'cookie or token or jwt ...\' param)') if auth: kwargs['auth'] = auth + + if "proxy" not in kwargs: + proxy = os.environ.get("G4F_PROXY") + if proxy: + kwargs['proxy'] = proxy result = provider.create_completion(model.name, messages, stream, **kwargs) return result if stream else ''.join(result) @@ -103,7 +81,7 @@ class ChatCompletion: @staticmethod async def create_async(model : Union[Model, str], messages : Messages, - provider : Union[type[BaseProvider], None] = None, + provider : Union[type[BaseProvider], str, None] = None, stream : bool = False, ignored : List[str] = None, **kwargs) -> Union[AsyncResult, str]: @@ -112,7 +90,7 @@ class ChatCompletion: if stream: if isinstance(provider, type) and issubclass(provider, AsyncGeneratorProvider): return await provider.create_async_generator(model.name, messages, **kwargs) - raise ValueError(f'{provider.__name__} does not support "stream" argument') + raise StreamNotSupportedError(f'{provider.__name__} does not support "stream" argument in "create_async"') return await provider.create_async(model.name, messages, **kwargs) @@ -132,9 +110,8 @@ class Completion: 'text-davinci-002', 'text-davinci-003' ] - if model not in allowed_models: - raise Exception(f'ValueError: Can\'t use {model} with Completion.create()') + raise ModelNotAllowed(f'Can\'t use {model} with Completion.create()') model, provider = get_model_and_provider(model, provider, stream, ignored) @@ -15,7 +15,7 @@ def main(): parser = argparse.ArgumentParser(description="Run gpt4free") subparsers = parser.add_subparsers(dest="mode", help="Mode to run the g4f in.") api_parser=subparsers.add_parser("api") - api_parser.add_argument("--bind", default="127.0.0.1:1337", help="The bind string.") + api_parser.add_argument("--bind", default="0.0.0.0:1337", help="The bind string.") api_parser.add_argument("--debug", type=bool, default=False, help="Enable verbose logging") api_parser.add_argument("--ignored-providers", nargs="+", choices=[provider.name for provider in IgnoredProviders], default=[], help="List of providers to ignore when processing request.") diff --git a/g4f/debug.py b/g4f/debug.py index 984d973a..1ee1506f 100644 --- a/g4f/debug.py +++ b/g4f/debug.py @@ -1,2 +1,39 @@ +from os import environ +from requests import get +from importlib.metadata import version as get_package_version, PackageNotFoundError +from subprocess import check_output, CalledProcessError, PIPE +from .errors import VersionNotFoundError + logging = False -version_check = True
\ No newline at end of file +version_check = True + +def get_version() -> str: + # Read from package manager + try: + return get_package_version("g4f") + except PackageNotFoundError: + pass + # Read from docker environment + current_version = environ.get("G4F_VERSION") + if current_version: + return current_version + # Read from git repository + try: + command = ["git", "describe", "--tags", "--abbrev=0"] + return check_output(command, text=True, stderr=PIPE).strip() + except CalledProcessError: + pass + raise VersionNotFoundError("Version not found") + +def get_lastet_version() -> str: + response = get("https://pypi.org/pypi/g4f/json").json() + return response["info"]["version"] + +def check_pypi_version() -> None: + try: + version = get_version() + latest_version = get_lastet_version() + if version != latest_version: + print(f'New pypi version: {latest_version} (current: {version}) | pip install -U g4f') + except Exception as e: + print(f'Failed to check g4f pypi version: {e}')
\ No newline at end of file diff --git a/g4f/errors.py b/g4f/errors.py new file mode 100644 index 00000000..b554aead --- /dev/null +++ b/g4f/errors.py @@ -0,0 +1,26 @@ +class ProviderNotFoundError(Exception): + pass + +class ProviderNotWorkingError(Exception): + pass + +class StreamNotSupportedError(Exception): + pass + +class AuthenticationRequiredError(Exception): + pass + +class ModelNotFoundError(Exception): + pass + +class ModelNotAllowed(Exception): + pass + +class RetryProviderError(Exception): + pass + +class RetryNoProviderError(Exception): + pass + +class VersionNotFoundError(Exception): + pass
\ No newline at end of file diff --git a/g4f/gui/client/css/style.css b/g4f/gui/client/css/style.css index 254a4b15..b6d73650 100644 --- a/g4f/gui/client/css/style.css +++ b/g4f/gui/client/css/style.css @@ -301,6 +301,9 @@ body { font-size: 15px; line-height: 1.3; } +.message .content pre { + white-space: pre-wrap; +} .message .user i { position: absolute; @@ -338,19 +341,15 @@ body { font-size: 14px; } - -.stop_generating { +.stop_generating, .regenerate { position: absolute; - bottom: 118px; - /* left: 10px; - bottom: 125px; - right: 8px; */ + bottom: 158px; left: 50%; transform: translateX(-50%); z-index: 1000000; } -.stop_generating button { +.stop_generating button, .regenerate button{ backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px); background-color: var(--blur-bg); @@ -380,11 +379,8 @@ body { } } -.stop_generating-hiding button { +.stop_generating-hidden #cancelButton, .regenerate-hidden #regenerateButton { animation: hide_popup 0.4s; -} - -.stop_generating-hidden button { display: none; } diff --git a/g4f/gui/client/html/index.html b/g4f/gui/client/html/index.html index 53c028d7..da7aeefb 100644 --- a/g4f/gui/client/html/index.html +++ b/g4f/gui/client/html/index.html @@ -101,6 +101,12 @@ <i class="fa-regular fa-stop"></i> </button> </div> + <div class="regenerate regenerate-hidden"> + <button id="regenerateButton"> + <span>Regenerate</span> + <i class="fa-solid fa-rotate"></i> + </button> + </div> <div class="box" id="messages"> </div> <div class="user-input"> diff --git a/g4f/gui/client/js/chat.v1.js b/g4f/gui/client/js/chat.v1.js index 2a1bdd73..644ff77a 100644 --- a/g4f/gui/client/js/chat.v1.js +++ b/g4f/gui/client/js/chat.v1.js @@ -5,15 +5,12 @@ const message_input = document.getElementById(`message-input`); const box_conversations = document.querySelector(`.top`); const spinner = box_conversations.querySelector(".spinner"); const stop_generating = document.querySelector(`.stop_generating`); +const regenerate = document.querySelector(`.regenerate`); const send_button = document.querySelector(`#send-button`); let prompt_lock = false; hljs.addPlugin(new CopyButtonPlugin()); -const format = (text) => { - return text.replace(/(?:\r\n|\r|\n)/g, "<br>"); -}; - message_input.addEventListener("blur", () => { window.scrollTo(0, 0); }); @@ -22,6 +19,10 @@ message_input.addEventListener("focus", () => { document.documentElement.scrollTop = document.documentElement.scrollHeight; }); +const markdown_render = (content) => { + return markdown.render(content).replace("<a href=", '<a target="_blank" href=').replace('<code>', '<code class="language-plaintext">') +} + const delete_conversations = async () => { localStorage.clear(); await new_conversation(); @@ -30,38 +31,25 @@ const delete_conversations = async () => { const handle_ask = async () => { message_input.style.height = `80px`; message_input.focus(); - - let txtMsgs = []; - const divTags = document.getElementsByClassName("message"); - for(let i=0;i<divTags.length;i++){ - if(!divTags[i].children[1].classList.contains("welcome-message")){ - if(divTags[i].children[0].className == "assistant"){ - const msg = { - role: "assistant", - content: divTags[i].children[1].textContent+" " - }; - txtMsgs.push(msg); - }else{ - const msg = { - role: "user", - content: divTags[i].children[1].textContent+" " - }; - txtMsgs.push(msg); - } - } - } - window.scrollTo(0, 0); - let message = message_input.value; - const msg = { - role: "user", - content: message - }; - txtMsgs.push(msg); - + message = message_input.value if (message.length > 0) { - message_input.value = ``; - await ask_gpt(txtMsgs); + message_input.value = ''; + await add_conversation(window.conversation_id, message); + await add_message(window.conversation_id, "user", message); + window.token = message_id(); + message_box.innerHTML += ` + <div class="message"> + <div class="user"> + ${user_image} + <i class="fa-regular fa-phone-arrow-up-right"></i> + </div> + <div class="content" id="user_${token}"> + ${markdown_render(message)} + </div> + </div> + `; + await ask_gpt(); } }; @@ -74,58 +62,40 @@ const remove_cancel_button = async () => { }, 300); }; -const ask_gpt = async (txtMsgs) => { - try { - message_input.value = ``; - message_input.innerHTML = ``; - message_input.innerText = ``; +const ask_gpt = async () => { + regenerate.classList.add(`regenerate-hidden`); + messages = await get_messages(window.conversation_id); - add_conversation(window.conversation_id, txtMsgs[0].content); - window.scrollTo(0, 0); - window.controller = new AbortController(); + window.scrollTo(0, 0); + window.controller = new AbortController(); - jailbreak = document.getElementById("jailbreak"); - provider = document.getElementById("provider"); - model = document.getElementById("model"); - prompt_lock = true; - window.text = ``; - window.token = message_id(); + jailbreak = document.getElementById("jailbreak"); + provider = document.getElementById("provider"); + model = document.getElementById("model"); + prompt_lock = true; + window.text = ``; - stop_generating.classList.remove(`stop_generating-hidden`); + stop_generating.classList.remove(`stop_generating-hidden`); - message_box.innerHTML += ` - <div class="message"> - <div class="user"> - ${user_image} - <i class="fa-regular fa-phone-arrow-up-right"></i> - </div> - <div class="content" id="user_${token}"> - ${format(txtMsgs[txtMsgs.length-1].content)} - </div> - </div> - `; - - message_box.scrollTop = message_box.scrollHeight; - window.scrollTo(0, 0); - await new Promise((r) => setTimeout(r, 500)); - window.scrollTo(0, 0); + message_box.scrollTop = message_box.scrollHeight; + window.scrollTo(0, 0); + await new Promise((r) => setTimeout(r, 500)); + window.scrollTo(0, 0); - message_box.innerHTML += ` - <div class="message"> - <div class="assistant"> - ${gpt_image} <i class="fa-regular fa-phone-arrow-down-left"></i> - </div> - <div class="content" id="gpt_${window.token}"> - <div id="cursor"></div> - </div> + message_box.innerHTML += ` + <div class="message"> + <div class="assistant"> + ${gpt_image} <i class="fa-regular fa-phone-arrow-down-left"></i> </div> - `; - - message_box.scrollTop = message_box.scrollHeight; - window.scrollTo(0, 0); - await new Promise((r) => setTimeout(r, 1000)); - window.scrollTo(0, 0); + <div class="content" id="gpt_${window.token}"> + <div id="cursor"></div> + </div> + </div> + `; + message_box.scrollTop = message_box.scrollHeight; + window.scrollTo(0, 0); + try { const response = await fetch(`/backend-api/v2/conversation`, { method: `POST`, signal: window.controller.signal, @@ -138,21 +108,22 @@ const ask_gpt = async (txtMsgs) => { action: `_ask`, model: model.options[model.selectedIndex].value, jailbreak: jailbreak.options[jailbreak.selectedIndex].value, + internet_access: document.getElementById(`switch`).checked, provider: provider.options[provider.selectedIndex].value, meta: { id: window.token, content: { - conversation: await get_conversation(window.conversation_id), - internet_access: document.getElementById(`switch`).checked, content_type: `text`, - parts: txtMsgs, + parts: messages, }, }, }), }); - const reader = response.body.getReader(); + await new Promise((r) => setTimeout(r, 1000)); + window.scrollTo(0, 0); + const reader = response.body.getReader(); while (true) { const { value, done } = await reader.read(); if (done) break; @@ -161,7 +132,7 @@ const ask_gpt = async (txtMsgs) => { text += chunk; - document.getElementById(`gpt_${window.token}`).innerHTML = markdown.render(text).replace("<a href=", '<a target="_blank" href='); + document.getElementById(`gpt_${window.token}`).innerHTML = markdown_render(text); document.querySelectorAll(`code`).forEach((el) => { hljs.highlightElement(el); }); @@ -171,45 +142,30 @@ const ask_gpt = async (txtMsgs) => { } if (text.includes(`G4F_ERROR`)) { - document.getElementById(`gpt_${window.token}`).innerHTML = "An error occured, please try again, if the problem persists, please reload / refresh cache or use a differnet browser"; + console.log("response", text); + document.getElementById(`gpt_${window.token}`).innerHTML = "An error occured, please try again, if the problem persists, please use a other model or provider"; } - - add_message(window.conversation_id, "user", txtMsgs[txtMsgs.length-1].content); - add_message(window.conversation_id, "assistant", text); - - message_box.scrollTop = message_box.scrollHeight; - await remove_cancel_button(); - prompt_lock = false; - - await load_conversations(20, 0); - window.scrollTo(0, 0); - } catch (e) { - add_message(window.conversation_id, "user", txtMsgs[txtMsgs.length-1].content); - - message_box.scrollTop = message_box.scrollHeight; - await remove_cancel_button(); - prompt_lock = false; - - await load_conversations(20, 0); - console.log(e); let cursorDiv = document.getElementById(`cursor`); if (cursorDiv) cursorDiv.parentNode.removeChild(cursorDiv); if (e.name != `AbortError`) { - let error_message = `oops ! something went wrong, please try again / reload. [stacktrace in console]`; - - document.getElementById(`gpt_${window.token}`).innerHTML = error_message; - add_message(window.conversation_id, "assistant", error_message); + text = `oops ! something went wrong, please try again / reload. [stacktrace in console]`; + document.getElementById(`gpt_${window.token}`).innerHTML = text; } else { document.getElementById(`gpt_${window.token}`).innerHTML += ` [aborted]`; - add_message(window.conversation_id, "assistant", text + ` [aborted]`); + text += ` [aborted]` } - - window.scrollTo(0, 0); } + add_message(window.conversation_id, "assistant", text); + message_box.scrollTop = message_box.scrollHeight; + await remove_cancel_button(); + prompt_lock = false; + window.scrollTo(0, 0); + await load_conversations(20, 0); + regenerate.classList.remove(`regenerate-hidden`); }; const clear_conversations = async () => { @@ -280,7 +236,6 @@ const set_conversation = async (conversation_id) => { }; const new_conversation = async () => { - history.pushState({}, null, `/chat/`); window.conversation_id = uuid(); @@ -291,12 +246,9 @@ const new_conversation = async () => { }; const load_conversation = async (conversation_id) => { - let conversation = await JSON.parse( - localStorage.getItem(`conversation:${conversation_id}`) - ); - console.log(conversation, conversation_id); + let messages = await get_messages(conversation_id); - for (item of conversation.items) { + for (item of messages) { message_box.innerHTML += ` <div class="message"> <div class=${item.role == "assistant" ? "assistant" : "user"}> @@ -308,7 +260,7 @@ const load_conversation = async (conversation_id) => { </div> <div class="content"> ${item.role == "assistant" - ? markdown.render(item.content).replace("<a href=", '<a target="_blank" href=') + ? markdown_render(item.content) : item.content } </div> @@ -331,6 +283,11 @@ const get_conversation = async (conversation_id) => { let conversation = await JSON.parse( localStorage.getItem(`conversation:${conversation_id}`) ); + return conversation; +}; + +const get_messages = async (conversation_id) => { + let conversation = await get_conversation(conversation_id); return conversation.items; }; @@ -351,21 +308,32 @@ const add_conversation = async (conversation_id, content) => { }) ); } + + history.pushState({}, null, `/chat/${conversation_id}`); }; -const add_message = async (conversation_id, role, content) => { - before_adding = JSON.parse( - localStorage.getItem(`conversation:${conversation_id}`) +const remove_last_message = async (conversation_id) => { + const conversation = await get_conversation(conversation_id) + + conversation.items.pop(); + + localStorage.setItem( + `conversation:${conversation_id}`, + JSON.stringify(conversation) ); +}; - before_adding.items.push({ +const add_message = async (conversation_id, role, content) => { + const conversation = await get_conversation(conversation_id); + + conversation.items.push({ role: role, content: content, }); localStorage.setItem( `conversation:${conversation_id}`, - JSON.stringify(before_adding) + JSON.stringify(conversation) ); }; @@ -404,6 +372,12 @@ document.getElementById(`cancelButton`).addEventListener(`click`, async () => { console.log(`aborted ${window.conversation_id}`); }); +document.getElementById(`regenerateButton`).addEventListener(`click`, async () => { + await remove_last_message(window.conversation_id); + window.token = message_id(); + await ask_gpt(); +}); + const uuid = () => { return `xxxxxxxx-xxxx-4xxx-yxxx-${Date.now().toString(16)}`.replace( /[xy]/g, @@ -485,17 +459,16 @@ const say_hello = async () => { ${gpt_image} <i class="fa-regular fa-phone-arrow-down-left"></i> </div> - <div class="content welcome-message"> + <div class="content"> + <p class=" welcome-message"></p> </div> </div> `; - content = `` to_modify = document.querySelector(`.welcome-message`); for (token of tokens) { await new Promise(resolve => setTimeout(resolve, (Math.random() * (100 - 200) + 100))) - content += token; - to_modify.innerHTML = markdown.render(content); + to_modify.textContent += token; } } @@ -542,14 +515,12 @@ window.onload = async () => { load_conversations(20, 0); }, 1); - if (!window.location.href.endsWith(`#`)) { - if (/\/chat\/.+/.test(window.location.href)) { - await load_conversation(window.conversation_id); - } + if (/\/chat\/.+/.test(window.location.href)) { + await load_conversation(window.conversation_id); + } else { + await say_hello() } - - await say_hello() - + message_input.addEventListener(`keydown`, async (evt) => { if (prompt_lock) return; if (evt.keyCode === 13 && !evt.shiftKey) { diff --git a/g4f/gui/run.py b/g4f/gui/run.py index 0f94814c..7ff769fd 100644 --- a/g4f/gui/run.py +++ b/g4f/gui/run.py @@ -6,7 +6,7 @@ from g4f.gui import run_gui def gui_parser(): parser = ArgumentParser(description="Run the GUI") parser.add_argument("-host", type=str, default="0.0.0.0", help="hostname") - parser.add_argument("-port", type=int, default=80, help="port") + parser.add_argument("-port", type=int, default=8080, help="port") parser.add_argument("-debug", action="store_true", help="debug mode") return parser diff --git a/g4f/gui/server/backend.py b/g4f/gui/server/backend.py index b0c55c8a..e4669699 100644 --- a/g4f/gui/server/backend.py +++ b/g4f/gui/server/backend.py @@ -1,14 +1,16 @@ import g4f from g4f.Provider import __providers__ -from flask import request +import json +from flask import request, Flask from .internet import get_search_message +from g4f import debug -g4f.debug.logging = True +debug.logging = True class Backend_Api: - def __init__(self, app) -> None: - self.app = app + def __init__(self, app: Flask) -> None: + self.app: Flask = app self.routes = { '/backend-api/v2/models': { 'function': self.models, @@ -51,8 +53,8 @@ class Backend_Api: def version(self): return { - "version": g4f.get_version(), - "lastet_version": g4f.get_lastet_version(), + "version": debug.get_version(), + "lastet_version": debug.get_lastet_version(), } def _gen_title(self): @@ -61,33 +63,31 @@ class Backend_Api: } def _conversation(self): - try: - #jailbreak = request.json['jailbreak'] - web_search = request.json['meta']['content']['internet_access'] - messages = request.json['meta']['content']['parts'] - if web_search: - messages[-1]["content"] = get_search_message(messages[-1]["content"]) - model = request.json.get('model') - model = model if model else g4f.models.default - provider = request.json.get('provider').replace('g4f.Provider.', '') - provider = provider if provider and provider != "Auto" else None - if provider != None: - provider = g4f.Provider.ProviderUtils.convert.get(provider) + #jailbreak = request.json['jailbreak'] + messages = request.json['meta']['content']['parts'] + if request.json['internet_access']: + messages[-1]["content"] = get_search_message(messages[-1]["content"]) + model = request.json.get('model') + model = model if model else g4f.models.default + provider = request.json.get('provider', '').replace('g4f.Provider.', '') + provider = provider if provider and provider != "Auto" else None + + def try_response(): + try: + yield from g4f.ChatCompletion.create( + model=model, + provider=provider, + messages=messages, + stream=True, + ignore_stream_and_auth=True + ) + except Exception as e: + print(e) + yield json.dumps({ + 'code' : 'G4F_ERROR', + '_action': '_ask', + 'success': False, + 'error' : f'{e.__class__.__name__}: {e}' + }) - response = g4f.ChatCompletion.create( - model=model, - provider=provider, - messages=messages, - stream=True, - ignore_stream_and_auth=True - ) - - return self.app.response_class(response, mimetype='text/event-stream') - - except Exception as e: - print(e) - return { - 'code' : 'G4F_ERROR', - '_action': '_ask', - 'success': False, - 'error' : f'an error occurred {str(e)}'}, 400 + return self.app.response_class(try_response(), mimetype='text/event-stream')
\ No newline at end of file |