From 74c399d675676938f31faf18174a98ed7a1709da Mon Sep 17 00:00:00 2001 From: Heiner Lohaus Date: Tue, 23 Apr 2024 17:34:42 +0200 Subject: Add conversation title change in gui Fix bug with multiple requests a .har in OpenaiChat --- g4f/Provider/Bing.py | 2 +- g4f/Provider/BingCreateImages.py | 14 ++++++---- g4f/Provider/HuggingChat.py | 3 ++ g4f/Provider/openai/har_file.py | 3 +- g4f/gui/client/static/css/style.css | 17 ++++++++++-- g4f/gui/client/static/js/chat.v1.js | 55 +++++++++++++++++++++++++++++-------- 6 files changed, 73 insertions(+), 21 deletions(-) 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 dd829a1a..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 { @@ -222,6 +224,9 @@ body { .conversations i, .bottom_buttons i { color: var(--conversations); cursor: pointer; +} + +.bottom_buttons i { width: 14px; } @@ -233,9 +238,17 @@ body { overflow: hidden; white-space: nowrap; margin-right: 10px; + background-color: transparent; + border: 0; + width: 100%; } -.convo-title .datetime { +.convo-title:focus { + outline: 1px solid var(--colour-3) !important; +} + +.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 += `
-
+
- ${updated} ${conversation.title} + ${updated} + ${conversation.new_title}