From 486e43dabd1198e6f3c94a4040fc01f5b2fe824c Mon Sep 17 00:00:00 2001 From: Heiner Lohaus Date: Tue, 19 Mar 2024 18:48:32 +0100 Subject: Fix missing websocket_request_id in OpenaiChat Add RateLimitErrors to Bing Add android support to gui api Add annotations import to gui api --- .gitignore | 3 +- g4f/Provider/Bing.py | 26 +++++----- g4f/Provider/bing/conversation.py | 3 ++ g4f/Provider/needs_auth/OpenaiChat.py | 2 +- g4f/gui/client/index.html | 6 +-- g4f/gui/client/static/css/style.css | 19 +++----- g4f/gui/client/static/js/chat.v1.js | 73 +++++++++++++++++++--------- g4f/gui/server/android_gallery.py | 67 ++++++++++++++++++++++++++ g4f/gui/server/api.py | 89 ++++++++++++++++++++++++++++++++++- g4f/gui/webview.py | 4 ++ requirements-min.txt | 3 +- setup.py | 1 + 12 files changed, 243 insertions(+), 53 deletions(-) create mode 100644 g4f/gui/server/android_gallery.py diff --git a/.gitignore b/.gitignore index b6c333e2..71d27a86 100644 --- a/.gitignore +++ b/.gitignore @@ -52,4 +52,5 @@ x.py info.txt local.py *.gguf -image.py \ No newline at end of file +image.py +.buildozer \ No newline at end of file diff --git a/g4f/Provider/Bing.py b/g4f/Provider/Bing.py index 7ff4d74b..0a0d2634 100644 --- a/g4f/Provider/Bing.py +++ b/g4f/Provider/Bing.py @@ -11,7 +11,7 @@ from aiohttp import ClientSession, ClientTimeout, BaseConnector, WSMsgType from ..typing import AsyncResult, Messages, ImageType, Cookies from ..image import ImageRequest -from ..errors import ResponseStatusError +from ..errors import ResponseStatusError, RateLimitError from .base_provider import AsyncGeneratorProvider, ProviderModelMixin from .helper import get_connector, get_random_hex from .bing.upload_image import upload_image @@ -26,7 +26,7 @@ class Tones: creative = "Creative" balanced = "Balanced" precise = "Precise" - copilot = "Balanced" + copilot = "Copilot" class Bing(AsyncGeneratorProvider, ProviderModelMixin): """ @@ -36,8 +36,8 @@ class Bing(AsyncGeneratorProvider, ProviderModelMixin): working = True supports_message_history = True supports_gpt_4 = True - default_model = "balanced" - models = [key for key in Tones.__dict__ if not key.startswith("__")] + default_model = "Balanced" + models = [getattr(Tones, key) for key in Tones.__dict__ if not key.startswith("__")] @classmethod def create_async_generator( @@ -72,7 +72,7 @@ class Bing(AsyncGeneratorProvider, ProviderModelMixin): context = create_context(messages[:-1]) if len(messages) > 1 else None if tone is None: tone = tone if model.startswith("gpt-4") else model - tone = cls.get_model("" if tone is None else tone.lower()) + tone = cls.get_model("" if tone is None else tone) gpt4_turbo = True if model.startswith("gpt-4-turbo") else False return stream_generate( @@ -258,7 +258,6 @@ class Defaults: 'sec-fetch-mode': 'cors', 'sec-fetch-dest': 'empty', 'referer': home, - 'accept-encoding': 'gzip, deflate, br', 'accept-language': 'en-US,en;q=0.9', } @@ -311,7 +310,7 @@ def create_message( "allowedMessageTypes": Defaults.allowedMessageTypes, "sliceIds": Defaults.sliceIds[tone], "verbosity": "verbose", - "scenario": "CopilotMicrosoftCom" if tone == "copilot" else "SERP", + "scenario": "CopilotMicrosoftCom" if tone == Tones.copilot else "SERP", "plugins": [{"id": "c310c353-b9f0-4d76-ab0d-1dd5e979cf68", "category": 1}] if web_search else [], "traceId": get_random_hex(40), "conversationHistoryOptionsSets": ["autosave","savemem","uprofupd","uprofgen"], @@ -329,7 +328,7 @@ def create_message( "requestId": request_id, "messageId": request_id }, - "tone": getattr(Tones, tone), + "tone": "Balanced" if tone == Tones.copilot else tone, "spokenTextMode": "None", "conversationId": conversation.conversationId, "participant": {"id": conversation.clientId} @@ -412,10 +411,15 @@ async def stream_generate( await asyncio.sleep(sleep_retry) continue - image_request = await upload_image(session, image, getattr(Tones, tone), headers) if image else None + image_request = await upload_image( + session, + image, + "Balanced" if Tones.copilot == "Copilot" else tone, + headers + ) if image else None async with session.ws_connect( 'wss://s.copilot.microsoft.com/sydney/ChatHub' - if tone == "copilot" else + if tone == "Copilot" else 'wss://sydney.bing.com/sydney/ChatHub', autoping=False, params={'sec_access_token': conversation.conversationSignature}, @@ -481,7 +485,7 @@ async def stream_generate( max_retries -= 1 if max_retries < 1: if result["value"] == "CaptchaChallenge": - raise RuntimeError(f"{result['value']}: Use other cookies or/and ip address") + raise RateLimitError(f"{result['value']}: Use other cookies or/and ip address") else: raise RuntimeError(f"{result['value']}: {result['message']}") if debug.logging: diff --git a/g4f/Provider/bing/conversation.py b/g4f/Provider/bing/conversation.py index 886efa68..de5716b7 100644 --- a/g4f/Provider/bing/conversation.py +++ b/g4f/Provider/bing/conversation.py @@ -2,6 +2,7 @@ from __future__ import annotations from aiohttp import ClientSession from ...requests import raise_for_status +from ...errors import RateLimitError class Conversation: """ @@ -36,6 +37,8 @@ async def create_conversation(session: ClientSession, headers: dict, tone: str) else: url = "https://www.bing.com/turing/conversation/create?bundleVersion=1.1626.1" async with session.get(url, headers=headers) as response: + if response.status == 404: + raise RateLimitError("Response 404: Do less requests and reuse conversations") await raise_for_status(response, "Failed to create conversation") data = await response.json() conversationId = data.get('conversationId') diff --git a/g4f/Provider/needs_auth/OpenaiChat.py b/g4f/Provider/needs_auth/OpenaiChat.py index 6601f500..8a5a03d4 100644 --- a/g4f/Provider/needs_auth/OpenaiChat.py +++ b/g4f/Provider/needs_auth/OpenaiChat.py @@ -450,7 +450,7 @@ class OpenaiChat(AsyncGeneratorProvider, ProviderModelMixin): ) as response: cls._update_request_args(session) await raise_for_status(response) - async for chunk in cls.iter_messages_chunk(response.iter_lines(), session, fields, websocket_request_id): + async for chunk in cls.iter_messages_chunk(response.iter_lines(), session, fields): if response_fields: response_fields = False yield fields diff --git a/g4f/gui/client/index.html b/g4f/gui/client/index.html index 9ce6b66a..6b9b1ab9 100644 --- a/g4f/gui/client/index.html +++ b/g4f/gui/client/index.html @@ -133,15 +133,15 @@
-