From 5dd8a625cc5f7592329b6b4a6c55ae15f4223401 Mon Sep 17 00:00:00 2001 From: xnny Date: Fri, 14 Jul 2023 16:15:31 +0800 Subject: [PATCH 01/16] fix server rejected WebSocket connection: HTTP 200 error --- src/EdgeGPT/chathub.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/EdgeGPT/chathub.py b/src/EdgeGPT/chathub.py index 3f5a92e5e..af79b5ed4 100644 --- a/src/EdgeGPT/chathub.py +++ b/src/EdgeGPT/chathub.py @@ -269,3 +269,4 @@ async def delete_conversation( async def close(self) -> None: await self.session.aclose() + # await self.aio_session.close() From 09b4f82ade52adf5127952003eb098de60852a5c Mon Sep 17 00:00:00 2001 From: Sergei Vedishchev Date: Sun, 16 Jul 2023 01:29:20 +0200 Subject: [PATCH 02/16] update edge headers --- src/EdgeGPT/constants.py | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/src/EdgeGPT/constants.py b/src/EdgeGPT/constants.py index d5426724e..82462ff76 100644 --- a/src/EdgeGPT/constants.py +++ b/src/EdgeGPT/constants.py @@ -1,4 +1,5 @@ import socket +# import random import uuid take_ip_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) @@ -7,28 +8,30 @@ take_ip_socket.close() DELIMITER = "\x1e" +# Generate random IP between range 13.104.0.0/14 +# FORWARDED_IP = f"1.0.0.{random.randint(0, 255)}" HEADERS = { "accept": "application/json", - "accept-language": "en-US;q=0.9", + "accept-language": "en-US,en;q=0.9", "accept-encoding": "gzip, deflate, br, zsdch", "content-type": "application/json", - "sec-ch-ua": '"Not/A)Brand";v="99", "Microsoft Edge";v="115", "Chromium";v="115"', + "sec-ch-ua": '"Not.A/Brand";v="8", "Chromium";v="114", "Microsoft Edge";v="114"', "sec-ch-ua-arch": '"x86"', "sec-ch-ua-bitness": '"64"', - "sec-ch-ua-full-version": '"115.0.1901.188"', - "sec-ch-ua-full-version-list": '"Not/A)Brand";v="99.0.0.0", "Microsoft Edge";v="115.0.1901.188", "Chromium";v="115.0.5790.114"', + "sec-ch-ua-full-version": '"114.0.1823.82"', + "sec-ch-ua-full-version-list": '"Not.A/Brand";v="8.0.0.0", "Chromium";v="114.0.5735.201", "Microsoft Edge";v="114.0.1823.82"', "sec-ch-ua-mobile": "?0", "sec-ch-ua-model": "", "sec-ch-ua-platform": '"Windows"', - "sec-ch-ua-platform-version": '"15.0.0"', + "sec-ch-ua-platform-version": '"14.0.0"', "sec-fetch-dest": "empty", "sec-fetch-mode": "cors", "sec-fetch-site": "same-origin", - "sec-ms-gec-version": "1-115.0.1901.188", + "sec-ms-gec-version": "1-114.0.1823.82", "x-ms-client-request-id": str(uuid.uuid4()), "x-ms-useragent": "azsdk-js-api-client-factory/1.0.0-beta.1 core-rest-pipeline/1.10.3 OS/Windows", - "Referer": "https://www.bing.com/search?", + "Referer": "https://www.bing.com/search?q=Bing+AI&showconv=1&FORM=hpcodx", "Referrer-Policy": "origin-when-cross-origin", "x-forwarded-for": FORWARDED_IP, } @@ -36,19 +39,19 @@ HEADERS_INIT_CONVER = { "authority": "www.bing.com", "accept": "application/json", - "accept-language": "en-US;q=0.9", + "accept-language": "en-US,en;q=0.9", "cache-control": "max-age=0", - "sec-ch-ua": '"Not/A)Brand";v="99", "Microsoft Edge";v="115", "Chromium";v="115"', + "sec-ch-ua": '"Not.A/Brand";v="8", "Chromium";v="114", "Microsoft Edge";v="114"', "sec-ch-ua-arch": '"x86"', "sec-ch-ua-bitness": '"64"', - "sec-ch-ua-full-version": '"115.0.1901.188"', - "sec-ch-ua-full-version-list": '"Not/A)Brand";v="99.0.0.0", "Microsoft Edge";v="115.0.1901.188", "Chromium";v="115.0.5790.114"', + "sec-ch-ua-full-version": '"114.0.1823.82"', + "sec-ch-ua-full-version-list": '"Not.A/Brand";v="8.0.0.0", "Chromium";v="114.0.5735.201", "Microsoft Edge";v="114.0.1823.82"', "sec-ch-ua-mobile": "?0", "sec-ch-ua-model": '""', "sec-ch-ua-platform": '"Windows"', - "sec-ch-ua-platform-version": '"15.0.0"', + "sec-ch-ua-platform-version": '"14.0.0"', "upgrade-insecure-requests": "1", - "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36 Edg/115.0.1901.188", + "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36 Edg/114.0.1823.82", "x-edge-shopping-flag": "1", "x-forwarded-for": FORWARDED_IP, } From 9d617bb731bbda1c8f2b6eba96cd28c934e733d1 Mon Sep 17 00:00:00 2001 From: Sergei Vedishchev Date: Mon, 24 Jul 2023 12:38:56 +0200 Subject: [PATCH 03/16] print response if KeyError caught --- src/EdgeGPT/chathub.py | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/EdgeGPT/chathub.py b/src/EdgeGPT/chathub.py index af79b5ed4..0ba4dc151 100644 --- a/src/EdgeGPT/chathub.py +++ b/src/EdgeGPT/chathub.py @@ -144,26 +144,26 @@ async def ask_stream( continue response = json.loads(obj) # print(response) - if response.get("type") == 1 and response["arguments"][0].get( - "messages", - ): - if not draw: - if ( - response["arguments"][0]["messages"][0].get( - "messageType", - ) - == "GenerateContentQuery" + if response.get("type") == 1 and response["arguments"][0].get( + "messages", ): - try: - async with ImageGenAsync( - all_cookies=self.cookies, - ) as image_generator: - images = await image_generator.get_images( - response["arguments"][0]["messages"][0]["text"], + if not draw: + if ( + response["arguments"][0]["messages"][0].get( + "messageType", ) - for i, image in enumerate(images): - resp_txt = f"{resp_txt}\n![image{i}]({image})" - draw = True + == "GenerateContentQuery" + ): + try: + async with ImageGenAsync( + all_cookies=self.cookies, + ) as image_generator: + images = await image_generator.get_images( + response["arguments"][0]["messages"][0]["text"], + ) + for i, image in enumerate(images): + resp_txt = f"{resp_txt}\n![image{i}]({image})" + draw = True except Exception as e: print(e) continue From fa62fc34ba77cf2629a61023038c4440995a1082 Mon Sep 17 00:00:00 2001 From: Sergei Vedishchev Date: Tue, 25 Jul 2023 20:06:18 +0200 Subject: [PATCH 04/16] Revert "print response if KeyError caught" This reverts commit 148e8b05df6471a7a7362eee5a17fecfff40d638. --- src/EdgeGPT/chathub.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/EdgeGPT/chathub.py b/src/EdgeGPT/chathub.py index 0ba4dc151..899c64b39 100644 --- a/src/EdgeGPT/chathub.py +++ b/src/EdgeGPT/chathub.py @@ -106,6 +106,8 @@ async def ask_stream( # Check if websocket is closed wss = await self.aio_session.ws_connect( wss_link or "wss://sydney.bing.com/sydney/ChatHub", + extra_headers=req_header, + max_size=None, ssl=ssl_context, headers=HEADERS, proxy=self.proxy, From a40674cd7164ce8e4884e7defbce37af6e30522a Mon Sep 17 00:00:00 2001 From: Sergei Vedishchev Date: Tue, 25 Jul 2023 23:43:02 +0200 Subject: [PATCH 05/16] Revert "fix server rejected WebSocket connection: HTTP 200 error" This reverts commit d9898b13dcffa7a5ffd1b60b4e8ae0f975136dc5. --- src/EdgeGPT/EdgeGPT.py | 1 - src/EdgeGPT/EdgeUtils.py | 7 +-- src/EdgeGPT/chathub.py | 106 +++++++++++++++++------------------- src/EdgeGPT/conversation.py | 3 +- 4 files changed, 53 insertions(+), 64 deletions(-) diff --git a/src/EdgeGPT/EdgeGPT.py b/src/EdgeGPT/EdgeGPT.py index 96564f1c6..86cde4651 100644 --- a/src/EdgeGPT/EdgeGPT.py +++ b/src/EdgeGPT/EdgeGPT.py @@ -4,7 +4,6 @@ from __future__ import annotations import json -from pathlib import Path from typing import Generator from .chathub import * diff --git a/src/EdgeGPT/EdgeUtils.py b/src/EdgeGPT/EdgeUtils.py index 09dcf7f5c..a5969ebe6 100644 --- a/src/EdgeGPT/EdgeUtils.py +++ b/src/EdgeGPT/EdgeUtils.py @@ -6,8 +6,7 @@ from log2d import Log -from .EdgeGPT import Chatbot -from .EdgeGPT import ConversationStyle +from .EdgeGPT import Chatbot, ConversationStyle from .ImageGen import ImageGen Log("BingChat") @@ -148,7 +147,7 @@ def __init__( if isinstance(x, (str, Path)) and x } Cookie.supplied_files = cookie_files - files = Cookie.files() # includes .supplied_files + Cookie.files() # includes .supplied_files if Cookie.rotate_cookies: Cookie.import_next() else: @@ -348,7 +347,7 @@ def test_cookie_rotation() -> None: log(f"Cookie count: {Cookie.request_count.get(Cookie.current_file_path.name)}") -def test_features() -> Query: +def test_features(i) -> Query: try: q = Query( f"What is {i} in Roman numerals? Give the answer in JSON", diff --git a/src/EdgeGPT/chathub.py b/src/EdgeGPT/chathub.py index 899c64b39..b45d3f50e 100644 --- a/src/EdgeGPT/chathub.py +++ b/src/EdgeGPT/chathub.py @@ -4,24 +4,18 @@ import ssl import sys from time import time -from typing import Generator -from typing import List -from typing import Union +from typing import Generator, List, Union import aiohttp import certifi import httpx from BingImageCreator import ImageGenAsync -from .constants import DELIMITER -from .constants import HEADERS -from .constants import HEADERS_INIT_CONVER +from .constants import DELIMITER, HEADERS, HEADERS_INIT_CONVER from .conversation import Conversation from .conversation_style import CONVERSATION_STYLE_TYPE from .request import ChatHubRequest -from .utilities import append_identifier -from .utilities import get_ran_hex -from .utilities import guess_locale +from .utilities import append_identifier, get_ran_hex, guess_locale ssl_context = ssl.create_default_context() ssl_context.load_verify_locations(certifi.where()) @@ -106,8 +100,6 @@ async def ask_stream( # Check if websocket is closed wss = await self.aio_session.ws_connect( wss_link or "wss://sydney.bing.com/sydney/ChatHub", - extra_headers=req_header, - max_size=None, ssl=ssl_context, headers=HEADERS, proxy=self.proxy, @@ -146,7 +138,7 @@ async def ask_stream( continue response = json.loads(obj) # print(response) - if response.get("type") == 1 and response["arguments"][0].get( + if response.get("type") == 1 and response["arguments"][0].get( "messages", ): if not draw: @@ -156,52 +148,52 @@ async def ask_stream( ) == "GenerateContentQuery" ): - try: - async with ImageGenAsync( - all_cookies=self.cookies, - ) as image_generator: - images = await image_generator.get_images( - response["arguments"][0]["messages"][0]["text"], - ) - for i, image in enumerate(images): - resp_txt = f"{resp_txt}\n![image{i}]({image})" - draw = True - except Exception as e: - print(e) - continue - if ( - ( - response["arguments"][0]["messages"][0]["contentOrigin"] - != "Apology" - ) - and not draw - and not raw - ): - resp_txt = result_text + response["arguments"][0][ - "messages" - ][0]["adaptiveCards"][0]["body"][0].get("text", "") - resp_txt_no_link = result_text + response["arguments"][0][ - "messages" - ][0].get("text", "") - if response["arguments"][0]["messages"][0].get( - "messageType", - ): - resp_txt = ( - resp_txt - + response["arguments"][0]["messages"][0][ - "adaptiveCards" - ][0]["body"][0]["inlines"][0].get("text") - + "\n" - ) - result_text = ( - result_text - + response["arguments"][0]["messages"][0][ - "adaptiveCards" - ][0]["body"][0]["inlines"][0].get("text") - + "\n" + try: + async with ImageGenAsync( + all_cookies=self.cookies, + ) as image_generator: + images = await image_generator.get_images( + response["arguments"][0]["messages"][0]["text"], + ) + for i, image in enumerate(images): + resp_txt = f"{resp_txt}\n![image{i}]({image})" + draw = True + except Exception as e: + print(e) + continue + if ( + ( + response["arguments"][0]["messages"][0]["contentOrigin"] + != "Apology" ) - if not raw: - yield False, resp_txt + and not draw + and not raw + ): + resp_txt = result_text + response["arguments"][0][ + "messages" + ][0]["adaptiveCards"][0]["body"][0].get("text", "") + resp_txt_no_link = result_text + response["arguments"][0][ + "messages" + ][0].get("text", "") + if response["arguments"][0]["messages"][0].get( + "messageType", + ): + resp_txt = ( + resp_txt + + response["arguments"][0]["messages"][0][ + "adaptiveCards" + ][0]["body"][0]["inlines"][0].get("text") + + "\n" + ) + result_text = ( + result_text + + response["arguments"][0]["messages"][0][ + "adaptiveCards" + ][0]["body"][0]["inlines"][0].get("text") + + "\n" + ) + if not raw: + yield False, resp_txt elif response.get("type") == 2: if response["item"]["result"].get("error"): diff --git a/src/EdgeGPT/conversation.py b/src/EdgeGPT/conversation.py index 99008bc0f..4bf105ec2 100644 --- a/src/EdgeGPT/conversation.py +++ b/src/EdgeGPT/conversation.py @@ -1,7 +1,6 @@ import json import os -from typing import List -from typing import Union +from typing import List, Union import httpx From 7ad23984fe6558008aa29c330f06121a7b317bfb Mon Sep 17 00:00:00 2001 From: Sergei Vedishchev Date: Wed, 2 Aug 2023 17:40:34 +0200 Subject: [PATCH 06/16] increased ws timeout --- src/EdgeGPT/chathub.py | 84 ++++++++++++++++++++++-------------------- 1 file changed, 45 insertions(+), 39 deletions(-) diff --git a/src/EdgeGPT/chathub.py b/src/EdgeGPT/chathub.py index b45d3f50e..2e8fc8555 100644 --- a/src/EdgeGPT/chathub.py +++ b/src/EdgeGPT/chathub.py @@ -103,6 +103,7 @@ async def ask_stream( ssl=ssl_context, headers=HEADERS, proxy=self.proxy, + timeout=30.0, ) await self._initial_handshake(wss) # Construct a ChatHub request @@ -137,8 +138,8 @@ async def ask_stream( if obj is None or not obj: continue response = json.loads(obj) - # print(response) - if response.get("type") == 1 and response["arguments"][0].get( + try: + if response.get("type") == 1 and response["arguments"][0].get( "messages", ): if not draw: @@ -195,43 +196,48 @@ async def ask_stream( if not raw: yield False, resp_txt - elif response.get("type") == 2: - if response["item"]["result"].get("error"): - await self.close() - raise Exception( - f"{response['item']['result']['value']}: {response['item']['result']['message']}", - ) - if draw: - cache = response["item"]["messages"][1]["adaptiveCards"][0][ - "body" - ][0]["text"] - response["item"]["messages"][1]["adaptiveCards"][0]["body"][0][ - "text" - ] = (cache + resp_txt) - if ( - response["item"]["messages"][-1]["contentOrigin"] == "Apology" - and resp_txt - ): - response["item"]["messages"][-1]["text"] = resp_txt_no_link - response["item"]["messages"][-1]["adaptiveCards"][0]["body"][0][ - "text" - ] = resp_txt - print( - "Preserved the message from being deleted", - file=sys.stderr, - ) - await wss.close() - if not self.aio_session.closed: - await self.aio_session.close() - yield True, response - return - if response.get("type") != 2: - if response.get("type") == 6: - await wss.send_str(append_identifier({"type": 6})) - elif response.get("type") == 7: - await wss.send_str(append_identifier({"type": 7})) - elif raw: - yield False, response + elif response.get("type") == 2: + if response["item"]["result"].get("error"): + await self.close() + raise Exception( + f"{response['item']['result']['value']}: {response['item']['result']['message']}", + ) + if draw: + cache = response["item"]["messages"][1]["adaptiveCards"][0][ + "body" + ][0]["text"] + response["item"]["messages"][1]["adaptiveCards"][0]["body"][0][ + "text" + ] = (cache + resp_txt) + if ( + response["item"]["messages"][-1]["contentOrigin"] == "Apology" + and resp_txt + ): + response["item"]["messages"][-1]["text"] = resp_txt_no_link + response["item"]["messages"][-1]["adaptiveCards"][0]["body"][0][ + "text" + ] = resp_txt + print( + "Preserved the message from being deleted", + file=sys.stderr, + ) + await wss.close() + if not self.aio_session.closed: + await self.aio_session.close() + yield True, response + return + if response.get("type") != 2: + if response.get("type") == 6: + await wss.send_str(append_identifier({"type": 6})) + elif response.get("type") == 7: + await wss.send_str(append_identifier({"type": 7})) + elif raw: + yield False, response + except Exception as e: + print(e) + print(response) + continue + async def _initial_handshake(self, wss) -> None: await wss.send_str(append_identifier({"protocol": "json", "version": 1})) From ea45de31dbeb19875d6582adf0ec7c6cbadaeef8 Mon Sep 17 00:00:00 2001 From: Sergei Vedishchev Date: Sat, 9 Sep 2023 14:19:53 +0200 Subject: [PATCH 07/16] fixing KeyError: 'conversationSignature' --- src/EdgeGPT/EdgeGPT.py | 3 --- src/EdgeGPT/chathub.py | 22 ++++------------------ src/EdgeGPT/conversation.py | 3 ++- 3 files changed, 6 insertions(+), 22 deletions(-) diff --git a/src/EdgeGPT/EdgeGPT.py b/src/EdgeGPT/EdgeGPT.py index 86cde4651..dd060b8f1 100644 --- a/src/EdgeGPT/EdgeGPT.py +++ b/src/EdgeGPT/EdgeGPT.py @@ -92,7 +92,6 @@ async def get_activity(self) -> dict: async def ask( self, prompt: str, - wss_link: str = "wss://sydney.bing.com/sydney/ChatHub", conversation_style: CONVERSATION_STYLE_TYPE = None, webpage_context: str | None = None, search_result: bool = False, @@ -115,7 +114,6 @@ async def ask( async for final, response in self.chat_hub.ask_stream( prompt=prompt, conversation_style=conversation_style, - wss_link=wss_link, webpage_context=webpage_context, search_result=search_result, locale=locale, @@ -173,7 +171,6 @@ async def ask( async def ask_stream( self, prompt: str, - wss_link: str = "wss://sydney.bing.com/sydney/ChatHub", conversation_style: CONVERSATION_STYLE_TYPE = None, raw: bool = False, webpage_context: str | None = None, diff --git a/src/EdgeGPT/chathub.py b/src/EdgeGPT/chathub.py index 2e8fc8555..c2ae66410 100644 --- a/src/EdgeGPT/chathub.py +++ b/src/EdgeGPT/chathub.py @@ -5,6 +5,7 @@ import sys from time import time from typing import Generator, List, Union +from urllib.parse import quote import aiohttp import certifi @@ -15,7 +16,7 @@ from .conversation import Conversation from .conversation_style import CONVERSATION_STYLE_TYPE from .request import ChatHubRequest -from .utilities import append_identifier, get_ran_hex, guess_locale +from .utilities import append_identifier, guess_locale ssl_context = ssl.create_default_context() ssl_context.load_verify_locations(certifi.where()) @@ -55,21 +56,6 @@ def __init__( headers=HEADERS_INIT_CONVER, ) - async def get_conversation( - self, - conversation_id: str = None, - conversation_signature: str = None, - client_id: str = None, - ) -> dict: - conversation_id = conversation_id or self.request.conversation_id - conversation_signature = ( - conversation_signature or self.request.conversation_signature - ) - client_id = client_id or self.request.client_id - url = f"https://sydney.bing.com/sydney/GetConversation?conversationId={conversation_id}&source=cib&participantId={client_id}&conversationSignature={conversation_signature}&traceId={get_ran_hex()}" - response = await self.session.get(url) - return response.json() - async def get_activity(self) -> dict: url = "https://www.bing.com/turing/conversation/chats" headers = HEADERS_INIT_CONVER.copy() @@ -84,7 +70,6 @@ async def get_activity(self) -> dict: async def ask_stream( self, prompt: str, - wss_link: str = None, conversation_style: CONVERSATION_STYLE_TYPE = None, raw: bool = False, webpage_context: Union[str, None] = None, @@ -98,8 +83,9 @@ async def ask_stream( cookies[cookie["name"]] = cookie["value"] self.aio_session = aiohttp.ClientSession(cookies=cookies) # Check if websocket is closed + token = quote(self.request.conversation_signature) wss = await self.aio_session.ws_connect( - wss_link or "wss://sydney.bing.com/sydney/ChatHub", + f"wss://sydney.bing.com/sydney/ChatHub?sec_access_token={token}", ssl=ssl_context, headers=HEADERS, proxy=self.proxy, diff --git a/src/EdgeGPT/conversation.py b/src/EdgeGPT/conversation.py index 4bf105ec2..f476b3e42 100644 --- a/src/EdgeGPT/conversation.py +++ b/src/EdgeGPT/conversation.py @@ -54,6 +54,7 @@ def __init__( raise Exception("Authentication failed") try: self.struct = response.json() + print(self.struct) except (json.decoder.JSONDecodeError, NotAllowedToAccess) as exc: raise Exception( "Authentication failed. You have not been accepted into the beta.", @@ -111,8 +112,8 @@ async def create( raise Exception("Authentication failed") try: self.struct = response.json() + self.struct["conversationSignature"] = response.headers["X-Sydney-Encryptedconversationsignature"] except (json.decoder.JSONDecodeError, NotAllowedToAccess) as exc: - print(response.text) raise Exception( "Authentication failed. You have not been accepted into the beta.", ) from exc From 366dc9d3509fe792541fca0a3679d89c723dc5a3 Mon Sep 17 00:00:00 2001 From: Sergei Vedishchev Date: Mon, 11 Sep 2023 14:58:00 +0200 Subject: [PATCH 08/16] return of conversationSignature --- src/EdgeGPT/chathub.py | 124 ++++++++++++++++++------------------ src/EdgeGPT/conversation.py | 7 +- 2 files changed, 67 insertions(+), 64 deletions(-) diff --git a/src/EdgeGPT/chathub.py b/src/EdgeGPT/chathub.py index c2ae66410..0789886e5 100644 --- a/src/EdgeGPT/chathub.py +++ b/src/EdgeGPT/chathub.py @@ -5,7 +5,6 @@ import sys from time import time from typing import Generator, List, Union -from urllib.parse import quote import aiohttp import certifi @@ -83,9 +82,8 @@ async def ask_stream( cookies[cookie["name"]] = cookie["value"] self.aio_session = aiohttp.ClientSession(cookies=cookies) # Check if websocket is closed - token = quote(self.request.conversation_signature) wss = await self.aio_session.ws_connect( - f"wss://sydney.bing.com/sydney/ChatHub?sec_access_token={token}", + "wss://sydney.bing.com/sydney/ChatHub", ssl=ssl_context, headers=HEADERS, proxy=self.proxy, @@ -126,61 +124,65 @@ async def ask_stream( response = json.loads(obj) try: if response.get("type") == 1 and response["arguments"][0].get( - "messages", - ): - if not draw: - if ( - response["arguments"][0]["messages"][0].get( - "messageType", - ) - == "GenerateContentQuery" - ): - try: - async with ImageGenAsync( - all_cookies=self.cookies, - ) as image_generator: - images = await image_generator.get_images( - response["arguments"][0]["messages"][0]["text"], - ) - for i, image in enumerate(images): - resp_txt = f"{resp_txt}\n![image{i}]({image})" - draw = True - except Exception as e: - print(e) - continue - if ( + "messages", + ): + if not draw: + if ( + response["arguments"][0]["messages"][0].get( + "messageType", + ) + == "GenerateContentQuery" + ): + try: + async with ImageGenAsync( + all_cookies=self.cookies, + ) as image_generator: + images = await image_generator.get_images( + response["arguments"][0]["messages"][0][ + "text" + ], + ) + for i, image in enumerate(images): + resp_txt = f"{resp_txt}\n![image{i}]({image})" + draw = True + except Exception as e: + print(e) + continue + if ( ( - response["arguments"][0]["messages"][0]["contentOrigin"] + response["arguments"][0]["messages"][0][ + "contentOrigin" + ] != "Apology" ) and not draw and not raw - ): - resp_txt = result_text + response["arguments"][0][ - "messages" - ][0]["adaptiveCards"][0]["body"][0].get("text", "") - resp_txt_no_link = result_text + response["arguments"][0][ - "messages" - ][0].get("text", "") - if response["arguments"][0]["messages"][0].get( - "messageType", - ): - resp_txt = ( - resp_txt - + response["arguments"][0]["messages"][0][ - "adaptiveCards" - ][0]["body"][0]["inlines"][0].get("text") - + "\n" - ) - result_text = ( - result_text - + response["arguments"][0]["messages"][0][ - "adaptiveCards" - ][0]["body"][0]["inlines"][0].get("text") - + "\n" - ) - if not raw: - yield False, resp_txt + ): + resp_txt = result_text + response["arguments"][0][ + "messages" + ][0]["adaptiveCards"][0]["body"][0].get("text", "") + resp_txt_no_link = result_text + response["arguments"][ + 0 + ]["messages"][0].get("text", "") + if response["arguments"][0]["messages"][0].get( + "messageType", + ): + resp_txt = ( + resp_txt + + response["arguments"][0]["messages"][0][ + "adaptiveCards" + ][0]["body"][0]["inlines"][0].get("text") + + "\n" + ) + result_text = ( + result_text + + response["arguments"][0]["messages"][0][ + "adaptiveCards" + ][0]["body"][0]["inlines"][0].get("text") + + "\n" + ) + if not raw: + yield False, resp_txt elif response.get("type") == 2: if response["item"]["result"].get("error"): @@ -192,17 +194,18 @@ async def ask_stream( cache = response["item"]["messages"][1]["adaptiveCards"][0][ "body" ][0]["text"] - response["item"]["messages"][1]["adaptiveCards"][0]["body"][0][ - "text" - ] = (cache + resp_txt) + response["item"]["messages"][1]["adaptiveCards"][0]["body"][ + 0 + ]["text"] = (cache + resp_txt) if ( - response["item"]["messages"][-1]["contentOrigin"] == "Apology" + response["item"]["messages"][-1]["contentOrigin"] + == "Apology" and resp_txt ): response["item"]["messages"][-1]["text"] = resp_txt_no_link - response["item"]["messages"][-1]["adaptiveCards"][0]["body"][0][ - "text" - ] = resp_txt + response["item"]["messages"][-1]["adaptiveCards"][0][ + "body" + ][0]["text"] = resp_txt print( "Preserved the message from being deleted", file=sys.stderr, @@ -223,7 +226,6 @@ async def ask_stream( print(e) print(response) continue - async def _initial_handshake(self, wss) -> None: await wss.send_str(append_identifier({"protocol": "json", "version": 1})) diff --git a/src/EdgeGPT/conversation.py b/src/EdgeGPT/conversation.py index f476b3e42..9bac625b7 100644 --- a/src/EdgeGPT/conversation.py +++ b/src/EdgeGPT/conversation.py @@ -91,7 +91,8 @@ async def create( if cookies: formatted_cookies = httpx.Cookies() for cookie in cookies: - formatted_cookies.set(cookie["name"], cookie["value"]) + if cookie["name"] in ["_U", "SUID"]: + formatted_cookies.set(cookie["name"], cookie["value"]) async with httpx.AsyncClient( proxies=proxy, timeout=30, @@ -112,11 +113,11 @@ async def create( raise Exception("Authentication failed") try: self.struct = response.json() - self.struct["conversationSignature"] = response.headers["X-Sydney-Encryptedconversationsignature"] except (json.decoder.JSONDecodeError, NotAllowedToAccess) as exc: raise Exception( "Authentication failed. You have not been accepted into the beta.", ) from exc if self.struct["result"]["value"] == "UnauthorizedRequest": - raise NotAllowedToAccess(self.struct["result"]["message"]) + print(self.struct) + raise NotAllowedToAccess(self.struct["result"]["value"]) return self From 3b2b482c2d034f24c545c8f8c0abf73ffe717f1c Mon Sep 17 00:00:00 2001 From: Jacob Gelling Date: Thu, 5 Oct 2023 09:41:44 +0200 Subject: [PATCH 09/16] Handle conversationSignature given in header --- src/EdgeGPT/chathub.py | 8 ++++++++ src/EdgeGPT/conversation.py | 6 ++++++ 2 files changed, 14 insertions(+) diff --git a/src/EdgeGPT/chathub.py b/src/EdgeGPT/chathub.py index 0789886e5..158a93aa7 100644 --- a/src/EdgeGPT/chathub.py +++ b/src/EdgeGPT/chathub.py @@ -10,6 +10,7 @@ import certifi import httpx from BingImageCreator import ImageGenAsync +import urllib.parse from .constants import DELIMITER, HEADERS, HEADERS_INIT_CONVER from .conversation import Conversation @@ -54,6 +55,10 @@ def __init__( timeout=900, headers=HEADERS_INIT_CONVER, ) + if conversation.struct.get("encryptedConversationSignature"): + self.encrypted_conversation_signature = conversation.struct["encryptedConversationSignature"] + else: + self.encrypted_conversation_signature = None async def get_activity(self) -> dict: url = "https://www.bing.com/turing/conversation/chats" @@ -76,6 +81,9 @@ async def ask_stream( locale: str = guess_locale(), ) -> Generator[bool, Union[dict, str], None]: """ """ + if self.encrypted_conversation_signature is not None: + wss_link = wss_link or "wss://sydney.bing.com/sydney/ChatHub" + wss_link += f"?sec_access_token={urllib.parse.quote(self.encrypted_conversation_signature)}" cookies = {} if self.cookies is not None: for cookie in self.cookies: diff --git a/src/EdgeGPT/conversation.py b/src/EdgeGPT/conversation.py index 9bac625b7..5aa515d11 100644 --- a/src/EdgeGPT/conversation.py +++ b/src/EdgeGPT/conversation.py @@ -55,6 +55,9 @@ def __init__( try: self.struct = response.json() print(self.struct) + if self.struct.get("conversationSignature") is None: + self.struct["conversationSignature"] = response.headers["X-Sydney-Conversationsignature"] + self.struct["encryptedConversationSignature"] = response.headers["X-Sydney-Encryptedconversationsignature"] except (json.decoder.JSONDecodeError, NotAllowedToAccess) as exc: raise Exception( "Authentication failed. You have not been accepted into the beta.", @@ -113,6 +116,9 @@ async def create( raise Exception("Authentication failed") try: self.struct = response.json() + if self.struct.get("conversationSignature") is None: + self.struct["conversationSignature"] = response.headers["X-Sydney-Conversationsignature"] + self.struct["encryptedConversationSignature"] = response.headers["X-Sydney-Encryptedconversationsignature"] except (json.decoder.JSONDecodeError, NotAllowedToAccess) as exc: raise Exception( "Authentication failed. You have not been accepted into the beta.", From 729c32bdb00263d32a2a66214b4c16e33d125cee Mon Sep 17 00:00:00 2001 From: Jacob Gelling Date: Sun, 8 Oct 2023 20:16:42 +0200 Subject: [PATCH 10/16] Merge pull request #1 from F33RNI/main Fix encrypted_conversation_signature --- src/EdgeGPT/EdgeGPT.py | 5 +++++ src/EdgeGPT/chathub.py | 13 ++++++++++--- src/EdgeGPT/request.py | 3 +++ 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/EdgeGPT/EdgeGPT.py b/src/EdgeGPT/EdgeGPT.py index dd060b8f1..b5040326d 100644 --- a/src/EdgeGPT/EdgeGPT.py +++ b/src/EdgeGPT/EdgeGPT.py @@ -51,6 +51,7 @@ async def save_conversation(self, filename: str) -> None: with open(filename, "w") as f: conversation_id = self.chat_hub.request.conversation_id conversation_signature = self.chat_hub.request.conversation_signature + encrypted_conversation_signature = self.chat_hub.request.encrypted_conversation_signature client_id = self.chat_hub.request.client_id invocation_id = self.chat_hub.request.invocation_id f.write( @@ -58,6 +59,7 @@ async def save_conversation(self, filename: str) -> None: { "conversation_id": conversation_id, "conversation_signature": conversation_signature, + "encrypted_conversation_signature": encrypted_conversation_signature, "client_id": client_id, "invocation_id": invocation_id, }, @@ -72,6 +74,7 @@ async def load_conversation(self, filename: str) -> None: conversation = json.load(f) self.chat_hub.request = ChatHubRequest( conversation_signature=conversation["conversation_signature"], + encrypted_conversation_signature=conversation["encrypted_conversation_signature"], client_id=conversation["client_id"], conversation_id=conversation["conversation_id"], invocation_id=conversation["invocation_id"], @@ -201,6 +204,7 @@ async def delete_conversation( self, conversation_id: str = None, conversation_signature: str = None, + encrypted_conversation_signature: str = None, client_id: str = None, ) -> None: """ @@ -209,6 +213,7 @@ async def delete_conversation( await self.chat_hub.delete_conversation( conversation_id=conversation_id, conversation_signature=conversation_signature, + encrypted_conversation_signature=encrypted_conversation_signature, client_id=client_id, ) diff --git a/src/EdgeGPT/chathub.py b/src/EdgeGPT/chathub.py index 158a93aa7..d9ea2b669 100644 --- a/src/EdgeGPT/chathub.py +++ b/src/EdgeGPT/chathub.py @@ -35,6 +35,7 @@ def __init__( self.task: asyncio.Task self.request = ChatHubRequest( conversation_signature=conversation.struct["conversationSignature"], + encrypted_conversation_signature=conversation.struct["encryptedConversationSignature"], client_id=conversation.struct["clientId"], conversation_id=conversation.struct["conversationId"], ) @@ -74,6 +75,7 @@ async def get_activity(self) -> dict: async def ask_stream( self, prompt: str, + wss_link: str = None, conversation_style: CONVERSATION_STYLE_TYPE = None, raw: bool = False, webpage_context: Union[str, None] = None, @@ -81,9 +83,9 @@ async def ask_stream( locale: str = guess_locale(), ) -> Generator[bool, Union[dict, str], None]: """ """ - if self.encrypted_conversation_signature is not None: + if self.request.encrypted_conversation_signature is not None: wss_link = wss_link or "wss://sydney.bing.com/sydney/ChatHub" - wss_link += f"?sec_access_token={urllib.parse.quote(self.encrypted_conversation_signature)}" + wss_link += f"?sec_access_token={urllib.parse.quote(self.request.encrypted_conversation_signature)}" cookies = {} if self.cookies is not None: for cookie in self.cookies: @@ -91,7 +93,7 @@ async def ask_stream( self.aio_session = aiohttp.ClientSession(cookies=cookies) # Check if websocket is closed wss = await self.aio_session.ws_connect( - "wss://sydney.bing.com/sydney/ChatHub", + wss_link or "wss://sydney.bing.com/sydney/ChatHub", ssl=ssl_context, headers=HEADERS, proxy=self.proxy, @@ -244,12 +246,16 @@ async def delete_conversation( self, conversation_id: str = None, conversation_signature: str = None, + encrypted_conversation_signature: str = None, client_id: str = None, ) -> None: conversation_id = conversation_id or self.request.conversation_id conversation_signature = ( conversation_signature or self.request.conversation_signature ) + encrypted_conversation_signature = ( + encrypted_conversation_signature or self.request.encrypted_conversation_signature + ) client_id = client_id or self.request.client_id url = "https://sydney.bing.com/sydney/DeleteSingleConversation" await self.session.post( @@ -257,6 +263,7 @@ async def delete_conversation( json={ "conversationId": conversation_id, "conversationSignature": conversation_signature, + "encryptedConversationSignature": encrypted_conversation_signature, "participant": {"id": client_id}, "source": "cib", "optionsSets": ["autosave"], diff --git a/src/EdgeGPT/request.py b/src/EdgeGPT/request.py index 70249bc44..6e24e10e6 100644 --- a/src/EdgeGPT/request.py +++ b/src/EdgeGPT/request.py @@ -13,6 +13,7 @@ class ChatHubRequest: def __init__( self, conversation_signature: str, + encrypted_conversation_signature: str, client_id: str, conversation_id: str, invocation_id: int = 3, @@ -22,6 +23,7 @@ def __init__( self.client_id: str = client_id self.conversation_id: str = conversation_id self.conversation_signature: str = conversation_signature + self.encrypted_conversation_signature: str = encrypted_conversation_signature self.invocation_id: int = invocation_id def update( @@ -123,6 +125,7 @@ def update( "tone": conversation_style.name.capitalize(), # Make first letter uppercase "requestId": message_id, "conversationSignature": self.conversation_signature, + "encryptedConversationSignature": self.encrypted_conversation_signature, "participant": { "id": self.client_id, }, From 8158a0d099cee5cc97d83bcffa07fe7a27a6087b Mon Sep 17 00:00:00 2001 From: MonsterDruide1 <5958456@gmail.com> Date: Thu, 14 Sep 2023 11:16:19 +0200 Subject: [PATCH 11/16] Fix 'adaptiveCards' error --- src/EdgeGPT/chathub.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/EdgeGPT/chathub.py b/src/EdgeGPT/chathub.py index d9ea2b669..ed5ad4dff 100644 --- a/src/EdgeGPT/chathub.py +++ b/src/EdgeGPT/chathub.py @@ -165,6 +165,11 @@ async def ask_stream( ] != "Apology" ) + and + ( + response["arguments"][0]["messages"][0].get("messageType") + != "AdsQuery" + ) and not draw and not raw ): From 95e30bf80be28c0e1e4ed2e21502f3ee6b0572a6 Mon Sep 17 00:00:00 2001 From: Sergei Vedishchev Date: Mon, 29 Jan 2024 17:14:52 +0100 Subject: [PATCH 12/16] add attachment file upload --- src/EdgeGPT/EdgeGPT.py | 12 ++++- src/EdgeGPT/chathub.py | 94 ++++++++++++++++++++++++++++++++-------- src/EdgeGPT/constants.py | 25 +++++++++-- src/EdgeGPT/request.py | 20 ++++++--- src/EdgeGPT/utilities.py | 11 ++++- 5 files changed, 133 insertions(+), 29 deletions(-) diff --git a/src/EdgeGPT/EdgeGPT.py b/src/EdgeGPT/EdgeGPT.py index b5040326d..d4a0c1512 100644 --- a/src/EdgeGPT/EdgeGPT.py +++ b/src/EdgeGPT/EdgeGPT.py @@ -51,7 +51,9 @@ async def save_conversation(self, filename: str) -> None: with open(filename, "w") as f: conversation_id = self.chat_hub.request.conversation_id conversation_signature = self.chat_hub.request.conversation_signature - encrypted_conversation_signature = self.chat_hub.request.encrypted_conversation_signature + encrypted_conversation_signature = ( + self.chat_hub.request.encrypted_conversation_signature + ) client_id = self.chat_hub.request.client_id invocation_id = self.chat_hub.request.invocation_id f.write( @@ -74,7 +76,9 @@ async def load_conversation(self, filename: str) -> None: conversation = json.load(f) self.chat_hub.request = ChatHubRequest( conversation_signature=conversation["conversation_signature"], - encrypted_conversation_signature=conversation["encrypted_conversation_signature"], + encrypted_conversation_signature=conversation[ + "encrypted_conversation_signature" + ], client_id=conversation["client_id"], conversation_id=conversation["conversation_id"], invocation_id=conversation["invocation_id"], @@ -100,6 +104,7 @@ async def ask( search_result: bool = False, locale: str = guess_locale(), simplify_response: bool = False, + attachment: str | None = None, ) -> dict: """ Ask a question to the bot @@ -120,6 +125,7 @@ async def ask( webpage_context=webpage_context, search_result=search_result, locale=locale, + attachment=attachment, ): if final: if not simplify_response: @@ -179,6 +185,7 @@ async def ask_stream( webpage_context: str | None = None, search_result: bool = False, locale: str = guess_locale(), + attachment: str | None = None, ) -> Generator[bool, dict | str, None]: """ Ask a question to the bot @@ -191,6 +198,7 @@ async def ask_stream( webpage_context=webpage_context, search_result=search_result, locale=locale, + attachment=attachment, ): yield response diff --git a/src/EdgeGPT/chathub.py b/src/EdgeGPT/chathub.py index ed5ad4dff..3943874d1 100644 --- a/src/EdgeGPT/chathub.py +++ b/src/EdgeGPT/chathub.py @@ -3,6 +3,8 @@ import os import ssl import sys +import urllib.parse +from base64 import b64encode from time import time from typing import Generator, List, Union @@ -10,13 +12,12 @@ import certifi import httpx from BingImageCreator import ImageGenAsync -import urllib.parse -from .constants import DELIMITER, HEADERS, HEADERS_INIT_CONVER +from .constants import DELIMITER, HEADERS, HEADERS_INIT_CONVER, KBLOB_HEADERS from .conversation import Conversation from .conversation_style import CONVERSATION_STYLE_TYPE from .request import ChatHubRequest -from .utilities import append_identifier, guess_locale +from .utilities import append_identifier, cookies_to_dict, guess_locale ssl_context = ssl.create_default_context() ssl_context.load_verify_locations(certifi.where()) @@ -35,7 +36,9 @@ def __init__( self.task: asyncio.Task self.request = ChatHubRequest( conversation_signature=conversation.struct["conversationSignature"], - encrypted_conversation_signature=conversation.struct["encryptedConversationSignature"], + encrypted_conversation_signature=conversation.struct[ + "encryptedConversationSignature" + ], client_id=conversation.struct["clientId"], conversation_id=conversation.struct["conversationId"], ) @@ -57,7 +60,9 @@ def __init__( headers=HEADERS_INIT_CONVER, ) if conversation.struct.get("encryptedConversationSignature"): - self.encrypted_conversation_signature = conversation.struct["encryptedConversationSignature"] + self.encrypted_conversation_signature = conversation.struct[ + "encryptedConversationSignature" + ] else: self.encrypted_conversation_signature = None @@ -81,16 +86,13 @@ async def ask_stream( webpage_context: Union[str, None] = None, search_result: bool = False, locale: str = guess_locale(), + attachment: Union[str, None] = None, ) -> Generator[bool, Union[dict, str], None]: """ """ if self.request.encrypted_conversation_signature is not None: wss_link = wss_link or "wss://sydney.bing.com/sydney/ChatHub" wss_link += f"?sec_access_token={urllib.parse.quote(self.request.encrypted_conversation_signature)}" - cookies = {} - if self.cookies is not None: - for cookie in self.cookies: - cookies[cookie["name"]] = cookie["value"] - self.aio_session = aiohttp.ClientSession(cookies=cookies) + self.aio_session = aiohttp.ClientSession(cookies=cookies_to_dict(self.cookies)) # Check if websocket is closed wss = await self.aio_session.ws_connect( wss_link or "wss://sydney.bing.com/sydney/ChatHub", @@ -100,6 +102,11 @@ async def ask_stream( timeout=30.0, ) await self._initial_handshake(wss) + + attachment_info = None + if attachment: + attachment_info = await self._upload_attachment(attachment) + # Construct a ChatHub request self.request.update( prompt=prompt, @@ -107,6 +114,7 @@ async def ask_stream( webpage_context=webpage_context, search_result=search_result, locale=locale, + attachment_info=attachment_info, ) # Send request await wss.send_str(append_identifier(self.request.struct)) @@ -165,11 +173,12 @@ async def ask_stream( ] != "Apology" ) - and - ( - response["arguments"][0]["messages"][0].get("messageType") - != "AdsQuery" - ) + and ( + response["arguments"][0]["messages"][0].get( + "messageType" + ) + != "AdsQuery" + ) and not draw and not raw ): @@ -211,7 +220,7 @@ async def ask_stream( ][0]["text"] response["item"]["messages"][1]["adaptiveCards"][0]["body"][ 0 - ]["text"] = (cache + resp_txt) + ]["text"] = cache + resp_txt if ( response["item"]["messages"][-1]["contentOrigin"] == "Apology" @@ -259,7 +268,8 @@ async def delete_conversation( conversation_signature or self.request.conversation_signature ) encrypted_conversation_signature = ( - encrypted_conversation_signature or self.request.encrypted_conversation_signature + encrypted_conversation_signature + or self.request.encrypted_conversation_signature ) client_id = client_id or self.request.client_id url = "https://sydney.bing.com/sydney/DeleteSingleConversation" @@ -278,3 +288,53 @@ async def delete_conversation( async def close(self) -> None: await self.session.aclose() # await self.aio_session.close() + + def _build_upload_arguments( + self, attachment: str, image_base64: bytes | None = None + ) -> aiohttp.FormData: + data = aiohttp.FormData() + payload = { + "imageInfo": {"url": attachment}, + "knowledgeRequest": { + "invokedSkills": ["ImageById"], + "subscriptionId": "Bing.Chat.Multimodal", + "invokedSkillsRequestData": {"enableFaceBlur": False}, + "convoData": { + "convoid": self.conversation_id, + "convotone": str(self.conversation_style.value), + }, + }, + } + data.add_field( + "knowledgeRequest", json.dumps(payload), content_type="application/json" + ) + if image_base64: + data.add_field( + "imageBase64", image_base64, content_type="application/octet-stream" + ) + return data + + async def upload_attachment(self, attachment: str) -> dict: + image_base64 = None + with open(attachment, "rb") as file: + image_base64 = b64encode(file.read()) + use_proxy = self.proxy is None + session = aiohttp.ClientSession( + headers=KBLOB_HEADERS, + cookies=cookies_to_dict(self.cookies), + trust_env=use_proxy, + connector=aiohttp.TCPConnector(verify_ssl=False) if use_proxy else None, + ) + data = self._build_upload_arguments(attachment, image_base64) + async with session.post( + "https://www.bing.com/images/kblob", data=data + ) as response: + if response.status != 200: + raise RuntimeError( + f"Failed to upload image, received status: {response.status}" + ) + response_dict = await response.json() + if not response_dict["blobId"] or len(response_dict["blobId"]) == 0: + raise RuntimeError("Failed to parse image info") + await session.close() + return response_dict diff --git a/src/EdgeGPT/constants.py b/src/EdgeGPT/constants.py index 82462ff76..f34391a8f 100644 --- a/src/EdgeGPT/constants.py +++ b/src/EdgeGPT/constants.py @@ -1,5 +1,4 @@ import socket -# import random import uuid take_ip_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) @@ -10,6 +9,7 @@ DELIMITER = "\x1e" # Generate random IP between range 13.104.0.0/14 # FORWARDED_IP = f"1.0.0.{random.randint(0, 255)}" +USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36 Edg/114.0.1823.82" HEADERS = { "accept": "application/json", @@ -31,8 +31,8 @@ "sec-ms-gec-version": "1-114.0.1823.82", "x-ms-client-request-id": str(uuid.uuid4()), "x-ms-useragent": "azsdk-js-api-client-factory/1.0.0-beta.1 core-rest-pipeline/1.10.3 OS/Windows", - "Referer": "https://www.bing.com/search?q=Bing+AI&showconv=1&FORM=hpcodx", - "Referrer-Policy": "origin-when-cross-origin", + "referer": "https://www.bing.com/search?q=Bing+AI&showconv=1&FORM=hpcodx", + "referrer-policy": "origin-when-cross-origin", "x-forwarded-for": FORWARDED_IP, } @@ -51,7 +51,24 @@ "sec-ch-ua-platform": '"Windows"', "sec-ch-ua-platform-version": '"14.0.0"', "upgrade-insecure-requests": "1", - "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36 Edg/114.0.1823.82", + "user-agent": USER_AGENT, + "x-edge-shopping-flag": "1", + "x-forwarded-for": FORWARDED_IP, +} + +KBLOB_HEADERS = { + "accept": "image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8", + "accept-encoding": "gzip, deflate, br", + "accept-language": "en-US,en;q=0.9", + "content-type": "multipart/form-data", + "referer": "https://www.bing.com/search?q=Bing+AI&showconv=1&FORM=hpcodx", + "sec-ch-ua": '"Not.A/Brand";v="8", "Chromium";v="114", "Microsoft Edge";v="114"', + "sec-ch-ua-mobile": "?0", + "sec-ch-ua-platform": '"Windows"', + "sec-fetch-dest": "empty", + "sec-fetch-mode": "cors", + "sec-fetch-site": "same-origin", + "user-agent": USER_AGENT, "x-edge-shopping-flag": "1", "x-forwarded-for": FORWARDED_IP, } diff --git a/src/EdgeGPT/request.py b/src/EdgeGPT/request.py index 6e24e10e6..5e51eea5b 100644 --- a/src/EdgeGPT/request.py +++ b/src/EdgeGPT/request.py @@ -2,11 +2,10 @@ from datetime import datetime from typing import Union -from .conversation_style import CONVERSATION_STYLE_TYPE -from .conversation_style import ConversationStyle -from .utilities import get_location_hint_from_locale -from .utilities import get_ran_hex -from .utilities import guess_locale +from .conversation_style import CONVERSATION_STYLE_TYPE, ConversationStyle +from .utilities import get_location_hint_from_locale, get_ran_hex, guess_locale + +BING_BLOB_URL = "https://copilot.microsoft.com/images/blob?bcid=" class ChatHubRequest: @@ -33,6 +32,7 @@ def update( webpage_context: Union[str, None] = None, search_result: bool = False, locale: str = guess_locale(), + attachment_info: dict | None = None, ) -> None: options = [ "deepleo", @@ -63,10 +63,17 @@ def update( # Get current time timestamp = datetime.now().strftime("%Y-%m-%dT%H:%M:%S") + offset_string + image_url, original_image_url = None, None + + if attachment_info: + image_url = BING_BLOB_URL + attachment_info["blobId"] + original_image_url = BING_BLOB_URL + attachment_info["blobId"] + self.struct = { "arguments": [ { "source": "cib", + "scenario": "SERP", "optionsSets": options, "allowedMessageTypes": [ "ActionRequest", @@ -121,8 +128,11 @@ def update( "messageType": "Chat", "messageId": message_id, "requestId": message_id, + "imageUrl": image_url, + "originalImageUrl": original_image_url, }, "tone": conversation_style.name.capitalize(), # Make first letter uppercase + "spokenTextMode": "None", "requestId": message_id, "conversationSignature": self.conversation_signature, "encryptedConversationSignature": self.encrypted_conversation_signature, diff --git a/src/EdgeGPT/utilities.py b/src/EdgeGPT/utilities.py index f54ccad7a..c5471c1ad 100644 --- a/src/EdgeGPT/utilities.py +++ b/src/EdgeGPT/utilities.py @@ -2,7 +2,7 @@ import locale import random import sys -from typing import Union +from typing import List, Union from .constants import DELIMITER from .locale import LocationHint @@ -35,3 +35,12 @@ def guess_locale() -> str: return "en-us" loc, _ = locale.getlocale() return loc.replace("_", "-") if loc else "en-us" + + +def cookies_to_dict(cookies: List[dict]) -> dict: + if cookies is None: + return None + all_cookies = {} + for cookie in cookies: + all_cookies[cookie["name"]] = cookie["value"] + return all_cookies From 3f4738178ccea4ce81b6831e16b48b40ab757849 Mon Sep 17 00:00:00 2001 From: bigbyto Date: Sun, 17 Dec 2023 04:16:40 +0800 Subject: [PATCH 13/16] feat: nosearchall,gpt4-turbo --- src/EdgeGPT/EdgeGPT.py | 8 ++ src/EdgeGPT/chathub.py | 128 +++++++++++++++--------------- src/EdgeGPT/conversation_style.py | 59 +++++--------- src/EdgeGPT/request.py | 49 +++++++----- 4 files changed, 118 insertions(+), 126 deletions(-) diff --git a/src/EdgeGPT/EdgeGPT.py b/src/EdgeGPT/EdgeGPT.py index d4a0c1512..e3370577d 100644 --- a/src/EdgeGPT/EdgeGPT.py +++ b/src/EdgeGPT/EdgeGPT.py @@ -105,6 +105,8 @@ async def ask( locale: str = guess_locale(), simplify_response: bool = False, attachment: str | None = None, + mode: str = None, + no_search: bool = True, ) -> dict: """ Ask a question to the bot @@ -126,6 +128,8 @@ async def ask( search_result=search_result, locale=locale, attachment=attachment, + mode=mode, + no_search=no_search, ): if final: if not simplify_response: @@ -186,6 +190,8 @@ async def ask_stream( search_result: bool = False, locale: str = guess_locale(), attachment: str | None = None, + mode: str = None, + no_search: bool = True, ) -> Generator[bool, dict | str, None]: """ Ask a question to the bot @@ -199,6 +205,8 @@ async def ask_stream( search_result=search_result, locale=locale, attachment=attachment, + mode=mode, + no_search=no_search, ): yield response diff --git a/src/EdgeGPT/chathub.py b/src/EdgeGPT/chathub.py index 3943874d1..ee77412f2 100644 --- a/src/EdgeGPT/chathub.py +++ b/src/EdgeGPT/chathub.py @@ -87,6 +87,8 @@ async def ask_stream( search_result: bool = False, locale: str = guess_locale(), attachment: Union[str, None] = None, + mode: str = None, + no_search: bool = True, ) -> Generator[bool, Union[dict, str], None]: """ """ if self.request.encrypted_conversation_signature is not None: @@ -115,6 +117,8 @@ async def ask_stream( search_result=search_result, locale=locale, attachment_info=attachment_info, + mode=mode, + no_search=no_search, ) # Send request await wss.send_str(append_identifier(self.request.struct)) @@ -145,12 +149,10 @@ async def ask_stream( "messages", ): if not draw: - if ( - response["arguments"][0]["messages"][0].get( - "messageType", - ) - == "GenerateContentQuery" - ): + msg_type = response["arguments"][0]["messages"][0].get( + "messageType" + ) + if msg_type == "GenerateContentQuery": try: async with ImageGenAsync( all_cookies=self.cookies, @@ -182,70 +184,67 @@ async def ask_stream( and not draw and not raw ): - resp_txt = result_text + response["arguments"][0][ - "messages" - ][0]["adaptiveCards"][0]["body"][0].get("text", "") + body = response["arguments"][0]["messages"][0][ + "adaptiveCards" + ][0]["body"][0] + resp_txt = result_text + body.get("text", "") resp_txt_no_link = result_text + response["arguments"][ 0 ]["messages"][0].get("text", "") - if response["arguments"][0]["messages"][0].get( - "messageType", - ): - resp_txt = ( - resp_txt - + response["arguments"][0]["messages"][0][ - "adaptiveCards" - ][0]["body"][0]["inlines"][0].get("text") - + "\n" - ) - result_text = ( - result_text - + response["arguments"][0]["messages"][0][ - "adaptiveCards" - ][0]["body"][0]["inlines"][0].get("text") - + "\n" - ) + if msg_type and "inlines" in body: + resp_txt = ( + resp_txt + body["inlines"][0].get("text") + "\n" + ) + result_text = ( + result_text + + response["arguments"][0]["messages"][0][ + "adaptiveCards" + ][0]["body"][0]["inlines"][0].get("text") + + "\n" + ) if not raw: yield False, resp_txt - elif response.get("type") == 2: - if response["item"]["result"].get("error"): - await self.close() - raise Exception( - f"{response['item']['result']['value']}: {response['item']['result']['message']}", - ) - if draw: - cache = response["item"]["messages"][1]["adaptiveCards"][0][ - "body" - ][0]["text"] - response["item"]["messages"][1]["adaptiveCards"][0]["body"][ - 0 - ]["text"] = cache + resp_txt - if ( - response["item"]["messages"][-1]["contentOrigin"] - == "Apology" - and resp_txt - ): - response["item"]["messages"][-1]["text"] = resp_txt_no_link - response["item"]["messages"][-1]["adaptiveCards"][0][ - "body" - ][0]["text"] = resp_txt - print( - "Preserved the message from being deleted", - file=sys.stderr, - ) - await wss.close() - if not self.aio_session.closed: - await self.aio_session.close() - yield True, response - return - if response.get("type") != 2: - if response.get("type") == 6: - await wss.send_str(append_identifier({"type": 6})) - elif response.get("type") == 7: - await wss.send_str(append_identifier({"type": 7})) - elif raw: - yield False, response + elif response.get("type") == 2: + if response["item"]["result"].get("error"): + await self.close() + raise Exception( + f"{response['item']['result']['value']}: {response['item']['result']['message']}", + ) + if draw: + cache = response["item"]["messages"][1][ + "adaptiveCards" + ][0]["body"][0]["text"] + response["item"]["messages"][1]["adaptiveCards"][0][ + "body" + ][0]["text"] = cache + resp_txt + if ( + response["item"]["messages"][-1]["contentOrigin"] + == "Apology" + and resp_txt + ): + response["item"]["messages"][-1][ + "text" + ] = resp_txt_no_link + response["item"]["messages"][-1]["adaptiveCards"][0][ + "body" + ][0]["text"] = resp_txt + print( + "Preserved the message from being deleted", + file=sys.stderr, + ) + await wss.close() + if not self.aio_session.closed: + await self.aio_session.close() + yield True, response + return + if response.get("type") != 2: + if response.get("type") == 6: + await wss.send_str(append_identifier({"type": 6})) + elif response.get("type") == 7: + await wss.send_str(append_identifier({"type": 7})) + elif raw: + yield False, response except Exception as e: print(e) print(response) @@ -287,7 +286,6 @@ async def delete_conversation( async def close(self) -> None: await self.session.aclose() - # await self.aio_session.close() def _build_upload_arguments( self, attachment: str, image_base64: bytes | None = None diff --git a/src/EdgeGPT/conversation_style.py b/src/EdgeGPT/conversation_style.py index a5c54d118..f9831e502 100644 --- a/src/EdgeGPT/conversation_style.py +++ b/src/EdgeGPT/conversation_style.py @@ -6,49 +6,26 @@ from typing_extensions import Literal from typing import Optional +_BASE_OPTION_SETS = [ + "nlu_direct_response_filter", + "deepleo", + "disable_emoji_spoken_text", + "responsible_ai_policy_235", + "enablemm", + "iycapbing", + "iyxapbing", + "dv3sugg", + "iyoloxap", + "iyoloneutral", + "gencontentv3", + "nojbf", +] class ConversationStyle(Enum): - creative = [ - "nlu_direct_response_filter", - "deepleo", - "disable_emoji_spoken_text", - "responsible_ai_policy_235", - "enablemm", - "h3imaginative", - "objopinion", - "dsblhlthcrd", - "dv3sugg", - "autosave", - "clgalileo", - "gencontentv3", - ] - balanced = [ - "nlu_direct_response_filter", - "deepleo", - "disable_emoji_spoken_text", - "responsible_ai_policy_235", - "enablemm", - "galileo", - "saharagenconv5", - "objopinion", - "dsblhlthcrd", - "dv3sugg", - "autosave", - ] - precise = [ - "nlu_direct_response_filter", - "deepleo", - "disable_emoji_spoken_text", - "responsible_ai_policy_235", - "enablemm", - "h3precise", - "objopinion", - "dsblhlthcrd", - "dv3sugg", - "autosave", - "clgalileo", - "gencontentv3", - ] + creative = _BASE_OPTION_SETS + ["h3imaginative"] + balanced = _BASE_OPTION_SETS + ["galileo"] + precise = _BASE_OPTION_SETS + ["h3precise"] + CONVERSATION_STYLE_TYPE = Optional[ diff --git a/src/EdgeGPT/request.py b/src/EdgeGPT/request.py index 5e51eea5b..99f8dd896 100644 --- a/src/EdgeGPT/request.py +++ b/src/EdgeGPT/request.py @@ -33,6 +33,8 @@ def update( search_result: bool = False, locale: str = guess_locale(), attachment_info: dict | None = None, + mode: str = None, + no_search: bool = True, ) -> None: options = [ "deepleo", @@ -44,6 +46,13 @@ def update( if not isinstance(conversation_style, ConversationStyle): conversation_style = getattr(ConversationStyle, conversation_style) options = conversation_style.value + #enable gpt4_turbo + if mode == 'gpt4-turbo': + options.append('dlgpt4t') + + if no_search: + options.append('nosearchall') + message_id = str(uuid.uuid4()) # Get the current local time now_local = datetime.now() @@ -92,26 +101,26 @@ def update( ], "sliceIds": [ "winmuid1tf", - "styleoff", - "ccadesk", - "smsrpsuppv4cf", - "ssrrcache", - "contansperf", - "crchatrev", - "winstmsg2tf", - "creatgoglt", - "creatorv2t", - "sydconfigoptt", - "adssqovroff", - "530pstho", - "517opinion", - "418dhlth", - "512sprtic1s0", - "emsgpr", - "525ptrcps0", + "newmma-prod", + "imgchatgptv2", + "tts2", + "voicelang2", + "anssupfotest", + "emptyoson", + "tempcacheread", + "temptacache", + "ctrlworkpay", + "winlongmsg2tf", + "628fabocs0", + "531rai268s0", + "602refusal", + "621alllocs0", + "621docxfmtho", + "621preclsvn", + "330uaug", "529rweas0", - "515oscfing2s0", - "524vidansgs0", + "0626snptrcs0", + "619dagslnv1nr" ], "verbosity": "verbose", "traceId": get_ran_hex(32), @@ -146,7 +155,7 @@ def update( "target": "chat", "type": 4, } - if search_result: + if (not no_search) and (search_result): have_search_result = [ "InternalSearchQuery", "InternalSearchResult", From 3dbdc066857f0335e3fe4e2316a07ec0aa4b74e3 Mon Sep 17 00:00:00 2001 From: Sergei Vedishchev Date: Mon, 29 Jan 2024 17:20:26 +0100 Subject: [PATCH 14/16] update locale info --- src/EdgeGPT/locale.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/EdgeGPT/locale.py b/src/EdgeGPT/locale.py index 06a422b02..5f8776294 100644 --- a/src/EdgeGPT/locale.py +++ b/src/EdgeGPT/locale.py @@ -48,14 +48,14 @@ class LocationHint(Enum): "locale": "en-IE", "LocationHint": [ { - "country": "Norway", + "country": "Ireland", "state": "", - "city": "Oslo", + "city": "Dublin", "timezoneoffset": 1, "countryConfidence": 8, "Center": { - "Latitude": 59.9139, - "Longitude": 10.7522, + "Latitude": 53.2732, + "Longitude": -6.2109, }, "RegionType": 2, "SourceType": 1, From 8b887e14b71cb1ce6fad1df00ff1b9029c014818 Mon Sep 17 00:00:00 2001 From: Sergei Vedishchev Date: Tue, 30 Jan 2024 21:36:30 +0100 Subject: [PATCH 15/16] bump setup version --- run.py | 27 +++++++++++++++++++++++++++ setup.py | 13 ++++++------- 2 files changed, 33 insertions(+), 7 deletions(-) create mode 100644 run.py diff --git a/run.py b/run.py new file mode 100644 index 000000000..66827acea --- /dev/null +++ b/run.py @@ -0,0 +1,27 @@ +import asyncio +import json + +from src.EdgeGPT.EdgeGPT import Chatbot, ConversationStyle + + +async def async_main() -> None: + """ + Main function + """ + print("Initializing...") + print("Enter `alt+enter` or `escape+enter` to send a message") + # Read and parse cookies + cookies = json.loads( + open("C:\\Users\\Codete\\.config\\bing-cookies.json", encoding="utf-8").read() + ) + bot = await Chatbot.create(cookies=cookies) + response = await bot.ask( + prompt="what parameters can be used in prompts with DALLE-3 in Bing Image Creator and for what purpose?", + conversation_style=ConversationStyle.balanced, + simplify_response=True, + ) + await bot.close() + print(json.dumps(response, indent=2)) + + +asyncio.run(async_main()) diff --git a/setup.py b/setup.py index 08b012e97..ff0e68890 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,6 @@ from pathlib import Path -from setuptools import find_packages -from setuptools import setup +from setuptools import find_packages, setup DOCS_PATH = Path(__file__).parents[0] / "docs/README.md" PATH = Path("README.md") @@ -11,16 +10,16 @@ f2.write(f1.read()) setup( - name="EdgeGPT", - version="0.13.2", + name="EdgeGPT-plus", + version="0.13.3", license="The Unlicense", - author="Antonio Cheong", + author="Antonio Cheong + others", author_email="acheong@student.dalat.org", description="Reverse engineered Edge Chat API", packages=find_packages("src"), package_dir={"": "src"}, - url="https://github.com/acheong08/EdgeGPT", - project_urls={"Bug Report": "https://github.com/acheong08/EdgeGPT/issues/new"}, + url="https://github.com/brainboost/EdgeGPT", + project_urls={"Bug Report": "https://github.com/brainboost/EdgeGPT/issues/new"}, entry_points={ "console_scripts": [ "edge-gpt = EdgeGPT.main:main", From 8c14ee437ad72dff4c6113de66b121e31f7cf3de Mon Sep 17 00:00:00 2001 From: Sergei Vedishchev Date: Sat, 3 Feb 2024 23:38:25 +0100 Subject: [PATCH 16/16] bump version --- requirements.txt | 3 ++- run.py | 5 +++-- setup.py | 4 ++-- src/EdgeGPT/EdgeGPT.py | 26 ++++++++++++++------------ src/EdgeGPT/chathub.py | 13 +++++++------ src/EdgeGPT/conversation.py | 18 +++++++++++++----- test_base.py | 14 ++++++++++---- 7 files changed, 51 insertions(+), 32 deletions(-) diff --git a/requirements.txt b/requirements.txt index 925cf46b5..59c012741 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,8 @@ aiohttp -BingImageCreator +BingImageCreator-plus certifi httpx prompt_toolkit requests rich +Brotli \ No newline at end of file diff --git a/run.py b/run.py index 66827acea..8a0503368 100644 --- a/run.py +++ b/run.py @@ -16,9 +16,10 @@ async def async_main() -> None: ) bot = await Chatbot.create(cookies=cookies) response = await bot.ask( - prompt="what parameters can be used in prompts with DALLE-3 in Bing Image Creator and for what purpose?", + prompt="please describe the picture", conversation_style=ConversationStyle.balanced, - simplify_response=True, + simplify_response=False, + attachment="C:\\Users\\Codete\\OneDrive\\Pictures\\Ffrc-8-XoAcItDo.jpg", ) await bot.close() print(json.dumps(response, indent=2)) diff --git a/setup.py b/setup.py index ff0e68890..c1a840b6a 100644 --- a/setup.py +++ b/setup.py @@ -11,7 +11,7 @@ setup( name="EdgeGPT-plus", - version="0.13.3", + version="0.13.6", license="The Unlicense", author="Antonio Cheong + others", author_email="acheong@student.dalat.org", @@ -34,7 +34,7 @@ "certifi", "prompt_toolkit", "requests", - "BingImageCreator>=0.4.4", + "BingImageCreator-plus>=0.4.4", ], long_description=Path.open(PATH, encoding="utf-8").read(), long_description_content_type="text/markdown", diff --git a/src/EdgeGPT/EdgeGPT.py b/src/EdgeGPT/EdgeGPT.py index e3370577d..64544079a 100644 --- a/src/EdgeGPT/EdgeGPT.py +++ b/src/EdgeGPT/EdgeGPT.py @@ -142,13 +142,19 @@ async def ask( ) if messages_left == 0: raise Exception("Max messages reached") - message = "" + message: dict | None = None + response_text = "" for msg in reversed(response["item"]["messages"]): - if msg.get("adaptiveCards") and msg["adaptiveCards"][0]["body"][ - 0 - ].get("text"): - message = msg - break + if msg.get("adaptiveCards"): + body = msg["adaptiveCards"][0]["body"] + for block in body: + if ( + block.get("type") == "TextBlock" + ): # the first block could be type: Image + response_text = block.get("text") + if response_text: + message = msg + break if not message: raise Exception("No message found") suggestions = [ @@ -156,12 +162,8 @@ async def ask( for suggestion in message.get("suggestedResponses", []) ] adaptive_cards = message.get("adaptiveCards", []) - adaptive_text = ( - adaptive_cards[0]["body"][0].get("text") if adaptive_cards else None - ) - sources = ( - adaptive_cards[0]["body"][0].get("text") if adaptive_cards else None - ) + adaptive_text = response_text if adaptive_cards else None + sources = response_text if adaptive_cards else None sources_text = ( adaptive_cards[0]["body"][-1].get("text") if adaptive_cards diff --git a/src/EdgeGPT/chathub.py b/src/EdgeGPT/chathub.py index ee77412f2..2b04494c7 100644 --- a/src/EdgeGPT/chathub.py +++ b/src/EdgeGPT/chathub.py @@ -12,6 +12,7 @@ import certifi import httpx from BingImageCreator import ImageGenAsync +from curl_cffi import requests from .constants import DELIMITER, HEADERS, HEADERS_INIT_CONVER, KBLOB_HEADERS from .conversation import Conversation @@ -91,6 +92,10 @@ async def ask_stream( no_search: bool = True, ) -> Generator[bool, Union[dict, str], None]: """ """ + attachment_info = None + if attachment: + attachment_info = await self.upload_attachment(attachment) + if self.request.encrypted_conversation_signature is not None: wss_link = wss_link or "wss://sydney.bing.com/sydney/ChatHub" wss_link += f"?sec_access_token={urllib.parse.quote(self.request.encrypted_conversation_signature)}" @@ -105,10 +110,6 @@ async def ask_stream( ) await self._initial_handshake(wss) - attachment_info = None - if attachment: - attachment_info = await self._upload_attachment(attachment) - # Construct a ChatHub request self.request.update( prompt=prompt, @@ -298,8 +299,8 @@ def _build_upload_arguments( "subscriptionId": "Bing.Chat.Multimodal", "invokedSkillsRequestData": {"enableFaceBlur": False}, "convoData": { - "convoid": self.conversation_id, - "convotone": str(self.conversation_style.value), + "convoid": self.request.conversation_id, + "convotone": "creative", }, }, } diff --git a/src/EdgeGPT/conversation.py b/src/EdgeGPT/conversation.py index 5aa515d11..838bd4d7a 100644 --- a/src/EdgeGPT/conversation.py +++ b/src/EdgeGPT/conversation.py @@ -56,8 +56,12 @@ def __init__( self.struct = response.json() print(self.struct) if self.struct.get("conversationSignature") is None: - self.struct["conversationSignature"] = response.headers["X-Sydney-Conversationsignature"] - self.struct["encryptedConversationSignature"] = response.headers["X-Sydney-Encryptedconversationsignature"] + self.struct["conversationSignature"] = response.headers[ + "X-Sydney-Conversationsignature" + ] + self.struct["encryptedConversationSignature"] = response.headers[ + "X-Sydney-Encryptedconversationsignature" + ] except (json.decoder.JSONDecodeError, NotAllowedToAccess) as exc: raise Exception( "Authentication failed. You have not been accepted into the beta.", @@ -94,7 +98,7 @@ async def create( if cookies: formatted_cookies = httpx.Cookies() for cookie in cookies: - if cookie["name"] in ["_U", "SUID"]: + if cookie["name"] in ["_U", "MUID"]: formatted_cookies.set(cookie["name"], cookie["value"]) async with httpx.AsyncClient( proxies=proxy, @@ -117,8 +121,12 @@ async def create( try: self.struct = response.json() if self.struct.get("conversationSignature") is None: - self.struct["conversationSignature"] = response.headers["X-Sydney-Conversationsignature"] - self.struct["encryptedConversationSignature"] = response.headers["X-Sydney-Encryptedconversationsignature"] + self.struct["conversationSignature"] = response.headers[ + "X-Sydney-Conversationsignature" + ] + self.struct["encryptedConversationSignature"] = response.headers[ + "X-Sydney-Encryptedconversationsignature" + ] except (json.decoder.JSONDecodeError, NotAllowedToAccess) as exc: raise Exception( "Authentication failed. You have not been accepted into the beta.", diff --git a/test_base.py b/test_base.py index 0957544e0..6726ad4f7 100644 --- a/test_base.py +++ b/test_base.py @@ -1,19 +1,25 @@ import json +import os import pytest -from EdgeGPT.EdgeGPT import Chatbot -from EdgeGPT.EdgeGPT import ConversationStyle + +from src.EdgeGPT.EdgeGPT import Chatbot, ConversationStyle pytest_plugins = ("pytest_asyncio",) from os import getenv +cookies = json.loads( + open("C:\\Users\\Codete\\.config\\bing-cookies_1.json", encoding="utf-8").read() +) + +# @pytest.disable() @pytest.mark.asyncio() async def test_ask() -> None: - bot = await Chatbot.create(cookies=getenv("EDGE_COOKIES")) + bot = await Chatbot.create(cookies=cookies or getenv("EDGE_COOKIES")) response = await bot.ask( - prompt="find me some information about the new ai released by meta.", + prompt="tell me a joke about cats", conversation_style=ConversationStyle.balanced, simplify_response=True, )