From ce45d36936b4d33ebc41c6687095ca511a175a35 Mon Sep 17 00:00:00 2001 From: Heiner Lohaus Date: Mon, 21 Aug 2023 22:39:57 +0200 Subject: Fix bing provider --- g4f/Provider/Bing.py | 464 ++++++++++++++++++++++----------------------------- 1 file changed, 203 insertions(+), 261 deletions(-) (limited to 'g4f/Provider/Bing.py') diff --git a/g4f/Provider/Bing.py b/g4f/Provider/Bing.py index 48b5477d..364e9c1d 100644 --- a/g4f/Provider/Bing.py +++ b/g4f/Provider/Bing.py @@ -2,17 +2,15 @@ import asyncio import json import os import random -import ssl -import uuid import aiohttp -import certifi -import requests +import asyncio +import browser_cookie3 +from aiohttp import ClientSession -from ..typing import Any, AsyncGenerator, CreateResult, Tuple, Union +from ..typing import Any, AsyncGenerator, CreateResult, Union from .base_provider import BaseProvider - class Bing(BaseProvider): url = "https://bing.com/chat" supports_gpt_4 = True @@ -22,20 +20,27 @@ class Bing(BaseProvider): model: str, messages: list[dict[str, str]], stream: bool, - **kwargs: Any, + **kwargs: Any ) -> CreateResult: - if len(messages) < 2: - prompt = messages[0]["content"] - context = False + yield from run(create(messages, **kwargs)) + +def create( + messages: list[dict[str, str]], + cookies: dict = {} + ): + if len(messages) < 2: + prompt = messages[0]["content"] + context = None - else: - prompt = messages[-1]["content"] - context = convert(messages[:-1]) + else: + prompt = messages[-1]["content"] + context = convert(messages[:-1]) - response = run(stream_generate(prompt, jailbreak, context)) - for token in response: - yield token + if not cookies: + for cookie in browser_cookie3.load(domain_name='.bing.com'): + cookies[cookie.name] = cookie.value + return stream_generate(prompt, context, cookies) def convert(messages: list[dict[str, str]]): context = "" @@ -45,250 +50,43 @@ def convert(messages: list[dict[str, str]]): return context - -jailbreak = { - "optionsSets": [ - "saharasugg", - "enablenewsfc", - "clgalileo", - "gencontentv3", - "nlu_direct_response_filter", - "deepleo", - "disable_emoji_spoken_text", - "responsible_ai_policy_235", - "enablemm", - "h3precise" - # "harmonyv3", - "dtappid", - "cricinfo", - "cricinfov2", - "dv3sugg", - "nojbfedge", - ] -} - - -ssl_context = ssl.create_default_context() -ssl_context.load_verify_locations(certifi.where()) - - -def _format(msg: dict[str, Any]) -> str: - return json.dumps(msg, ensure_ascii=False) + Defaults.delimiter - - -async def stream_generate( - prompt: str, - mode: dict[str, list[str]] = jailbreak, - context: Union[bool, str] = False, -): - timeout = aiohttp.ClientTimeout(total=900) - session = aiohttp.ClientSession(timeout=timeout) - - conversationId, clientId, conversationSignature = await create_conversation() - - wss = await session.ws_connect( - "wss://sydney.bing.com/sydney/ChatHub", - ssl=ssl_context, - autoping=False, - headers={ - "accept": "application/json", - "accept-language": "en-US,en;q=0.9", - "content-type": "application/json", - "sec-ch-ua": '"Not_A Brand";v="99", "Microsoft Edge";v="110", "Chromium";v="110"', - "sec-ch-ua-arch": '"x86"', - "sec-ch-ua-bitness": '"64"', - "sec-ch-ua-full-version": '"109.0.1518.78"', - "sec-ch-ua-full-version-list": '"Chromium";v="110.0.5481.192", "Not A(Brand";v="24.0.0.0", "Microsoft Edge";v="110.0.1587.69"', - "sec-ch-ua-mobile": "?0", - "sec-ch-ua-model": "", - "sec-ch-ua-platform": '"Windows"', - "sec-ch-ua-platform-version": '"15.0.0"', - "sec-fetch-dest": "empty", - "sec-fetch-mode": "cors", - "sec-fetch-site": "same-origin", - "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.0 OS/Win32", - "Referer": "https://www.bing.com/search?q=Bing+AI&showconv=1&FORM=hpcodx", - "Referrer-Policy": "origin-when-cross-origin", - "x-forwarded-for": Defaults.ip_address, - }, - ) - - await wss.send_str(_format({"protocol": "json", "version": 1})) - await wss.receive(timeout=900) - - argument: dict[str, Any] = { - **mode, +class Conversation(): + def __init__(self, conversationId: str, clientId: str, conversationSignature: str) -> None: + self.conversationId = conversationId + self.clientId = clientId + self.conversationSignature = conversationSignature + +async def create_conversation(session: ClientSession) -> Conversation: + url = 'https://www.bing.com/turing/conversation/create' + async with await session.get(url) as response: + response = await response.json() + conversationId = response.get('conversationId') + clientId = response.get('clientId') + conversationSignature = response.get('conversationSignature') + + if not conversationId or not clientId or not conversationSignature: + raise Exception('Failed to create conversation.') + + return Conversation(conversationId, clientId, conversationSignature) + +async def list_conversations(session: ClientSession) -> list: + url = "https://www.bing.com/turing/conversation/chats" + async with session.get(url) as response: + response = await response.json() + return response["chats"] + +async def delete_conversation(session: ClientSession, conversation: Conversation) -> list: + url = "https://sydney.bing.com/sydney/DeleteSingleConversation" + json = { + "conversationId": conversation.conversationId, + "conversationSignature": conversation.conversationSignature, + "participant": {"id": conversation.clientId}, "source": "cib", - "allowedMessageTypes": Defaults.allowedMessageTypes, - "sliceIds": Defaults.sliceIds, - "traceId": os.urandom(16).hex(), - "isStartOfSession": True, - "message": Defaults.location - | { - "author": "user", - "inputMethod": "Keyboard", - "text": prompt, - "messageType": "Chat", - }, - "conversationSignature": conversationSignature, - "participant": {"id": clientId}, - "conversationId": conversationId, + "optionsSets": ["autosave"] } - - if context: - argument["previousMessages"] = [ - { - "author": "user", - "description": context, - "contextType": "WebPage", - "messageType": "Context", - "messageId": "discover-web--page-ping-mriduna-----", - } - ] - - struct: dict[str, list[dict[str, Any]] | str | int] = { - "arguments": [argument], - "invocationId": "0", - "target": "chat", - "type": 4, - } - - await wss.send_str(_format(struct)) - - final = False - draw = False - resp_txt = "" - result_text = "" - resp_txt_no_link = "" - cache_text = "" - - while not final: - msg = await wss.receive(timeout=900) - objects = msg.data.split(Defaults.delimiter) # type: ignore - - for obj in objects: # type: ignore - if obj is None or not obj: - continue - - response = json.loads(obj) # type: ignore - if response.get("type") == 1 and response["arguments"][0].get( - "messages", - ): - if not draw: - if ( - response["arguments"][0]["messages"][0]["contentOrigin"] - != "Apology" - ) and not draw: - 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 cache_text.endswith(" "): - final = True - if wss and not wss.closed: - await wss.close() - if session and not session.closed: - await session.close() - - yield (resp_txt.replace(cache_text, "")) - cache_text = resp_txt - - elif response.get("type") == 2: - if response["item"]["result"].get("error"): - if wss and not wss.closed: - await wss.close() - if session and not session.closed: - await session.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) - - final = True - if wss and not wss.closed: - await wss.close() - if session and not session.closed: - await session.close() - - -async def create_conversation() -> Tuple[str, str, str]: - create = requests.get( - "https://www.bing.com/turing/conversation/create", - headers={ - "authority": "edgeservices.bing.com", - "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", - "accept-language": "en-US,en;q=0.9", - "cache-control": "max-age=0", - "sec-ch-ua": '"Chromium";v="110", "Not A(Brand";v="24", "Microsoft Edge";v="110"', - "sec-ch-ua-arch": '"x86"', - "sec-ch-ua-bitness": '"64"', - "sec-ch-ua-full-version": '"110.0.1587.69"', - "sec-ch-ua-full-version-list": '"Chromium";v="110.0.5481.192", "Not A(Brand";v="24.0.0.0", "Microsoft Edge";v="110.0.1587.69"', - "sec-ch-ua-mobile": "?0", - "sec-ch-ua-model": '""', - "sec-ch-ua-platform": '"Windows"', - "sec-ch-ua-platform-version": '"15.0.0"', - "sec-fetch-dest": "document", - "sec-fetch-mode": "navigate", - "sec-fetch-site": "none", - "sec-fetch-user": "?1", - "upgrade-insecure-requests": "1", - "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36 Edg/110.0.1587.69", - "x-edge-shopping-flag": "1", - "x-forwarded-for": Defaults.ip_address, - }, - ) - - conversationId = create.json().get("conversationId") - clientId = create.json().get("clientId") - conversationSignature = create.json().get("conversationSignature") - - if not conversationId or not clientId or not conversationSignature: - raise Exception("Failed to create conversation.") - - return conversationId, clientId, conversationSignature - + async with session.post(url, json=json) as response: + response = await response.json() + return response["result"]["value"] == "Success" class Defaults: delimiter = "\x1e" @@ -309,9 +107,6 @@ class Defaults: ] sliceIds = [ - # "222dtappid", - # "225cricinfo", - # "224locals0" "winmuid3tf", "osbsdusgreccf", "ttstmout", @@ -349,6 +144,153 @@ class Defaults: ], } + headers = { + 'accept': '*/*', + 'accept-language': 'en-US,en;q=0.9', + 'cache-control': 'max-age=0', + 'sec-ch-ua': '"Chromium";v="110", "Not A(Brand";v="24", "Microsoft Edge";v="110"', + 'sec-ch-ua-arch': '"x86"', + 'sec-ch-ua-bitness': '"64"', + 'sec-ch-ua-full-version': '"110.0.1587.69"', + 'sec-ch-ua-full-version-list': '"Chromium";v="110.0.5481.192", "Not A(Brand";v="24.0.0.0", "Microsoft Edge";v="110.0.1587.69"', + 'sec-ch-ua-mobile': '?0', + 'sec-ch-ua-model': '""', + 'sec-ch-ua-platform': '"Windows"', + 'sec-ch-ua-platform-version': '"15.0.0"', + 'sec-fetch-dest': 'document', + 'sec-fetch-mode': 'navigate', + 'sec-fetch-site': 'none', + 'sec-fetch-user': '?1', + 'upgrade-insecure-requests': '1', + 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36 Edg/110.0.1587.69', + 'x-edge-shopping-flag': '1', + 'x-forwarded-for': ip_address, + } + + optionsSets = { + "optionsSets": [ + 'saharasugg', + 'enablenewsfc', + 'clgalileo', + 'gencontentv3', + "nlu_direct_response_filter", + "deepleo", + "disable_emoji_spoken_text", + "responsible_ai_policy_235", + "enablemm", + "h3precise" + "dtappid", + "cricinfo", + "cricinfov2", + "dv3sugg", + "nojbfedge" + ] + } + +def format_message(msg: dict) -> str: + return json.dumps(msg, ensure_ascii=False) + Defaults.delimiter + +def create_message(conversation: Conversation, prompt: str, context: str=None) -> str: + struct = { + 'arguments': [ + { + **Defaults.optionsSets, + 'source': 'cib', + 'allowedMessageTypes': Defaults.allowedMessageTypes, + 'sliceIds': Defaults.sliceIds, + 'traceId': os.urandom(16).hex(), + 'isStartOfSession': True, + 'message': Defaults.location | { + 'author': 'user', + 'inputMethod': 'Keyboard', + 'text': prompt, + 'messageType': 'Chat' + }, + 'conversationSignature': conversation.conversationSignature, + 'participant': { + 'id': conversation.clientId + }, + 'conversationId': conversation.conversationId + } + ], + 'invocationId': '0', + 'target': 'chat', + 'type': 4 + } + + if context: + struct['arguments'][0]['previousMessages'] = [{ + "author": "user", + "description": context, + "contextType": "WebPage", + "messageType": "Context", + "messageId": "discover-web--page-ping-mriduna-----" + }] + return format_message(struct) + +async def stream_generate( + prompt: str, + context: str=None, + cookies: dict=None + ): + async with ClientSession( + timeout=aiohttp.ClientTimeout(total=900), + cookies=cookies, + headers=Defaults.headers, + ) as session: + conversation = await create_conversation(session) + try: + async with session.ws_connect( + 'wss://sydney.bing.com/sydney/ChatHub', + autoping=False, + ) as wss: + + await wss.send_str(format_message({'protocol': 'json', 'version': 1})) + msg = await wss.receive(timeout=900) + + await wss.send_str(create_message(conversation, prompt, context)) + + response_txt = '' + result_text = '' + returned_text = '' + final = False + + while not final: + msg = await wss.receive(timeout=900) + objects = msg.data.split(Defaults.delimiter) + for obj in objects: + if obj is None or not obj: + continue + + response = json.loads(obj) + if response.get('type') == 1 and response['arguments'][0].get('messages'): + message = response['arguments'][0]['messages'][0] + if (message['contentOrigin'] != 'Apology'): + response_txt = result_text + \ + message['adaptiveCards'][0]['body'][0].get('text', '') + + if message.get('messageType'): + inline_txt = message['adaptiveCards'][0]['body'][0]['inlines'][0].get('text') + response_txt += inline_txt + '\n' + result_text += inline_txt + '\n' + + if returned_text.endswith(' '): + final = True + break + + if response_txt.startswith(returned_text): + new = response_txt[len(returned_text):] + if new != "\n": + yield new + returned_text = response_txt + elif response.get('type') == 2: + result = response['item']['result'] + if result.get('error'): + raise Exception(f"{result['value']}: {result['message']}") + final = True + break + finally: + await delete_conversation(session, conversation) def run(generator: AsyncGenerator[Union[Any, str], Any]): loop = asyncio.get_event_loop() -- cgit v1.2.3 From d1b6921b5fa3d9dbd7f1cce6e4f396744a7a2274 Mon Sep 17 00:00:00 2001 From: Heiner Lohaus Date: Wed, 23 Aug 2023 02:16:35 +0200 Subject: Add create_async method --- g4f/Provider/Bing.py | 58 +++++++++++++++++++++++++++++++++++----------------- 1 file changed, 39 insertions(+), 19 deletions(-) (limited to 'g4f/Provider/Bing.py') diff --git a/g4f/Provider/Bing.py b/g4f/Provider/Bing.py index 364e9c1d..b9b9e9a4 100644 --- a/g4f/Provider/Bing.py +++ b/g4f/Provider/Bing.py @@ -13,34 +13,54 @@ from .base_provider import BaseProvider class Bing(BaseProvider): url = "https://bing.com/chat" + working = True supports_gpt_4 = True - @staticmethod + @classmethod def create_completion( + cls, model: str, messages: list[dict[str, str]], stream: bool, **kwargs: Any ) -> CreateResult: - yield from run(create(messages, **kwargs)) - -def create( + if stream: + yield from run(cls.create_async_generator(model, messages, **kwargs)) + else: + yield asyncio.run(cls.create_async(model, messages, **kwargs)) + + @classmethod + async def create_async( + cls, + model: str, messages: list[dict[str, str]], - cookies: dict = {} - ): - if len(messages) < 2: - prompt = messages[0]["content"] - context = None - - else: - prompt = messages[-1]["content"] - context = convert(messages[:-1]) - - if not cookies: - for cookie in browser_cookie3.load(domain_name='.bing.com'): - cookies[cookie.name] = cookie.value - - return stream_generate(prompt, context, cookies) + **kwargs: Any, + ) -> str: + result = [] + async for chunk in cls.create_async_generator(model, messages, **kwargs): + result.append(chunk) + if result: + return "".join(result) + + @staticmethod + def create_async_generator( + model: str, + messages: list[dict[str, str]], + cookies: dict = {} + ) -> AsyncGenerator: + if len(messages) < 2: + prompt = messages[0]["content"] + context = None + + else: + prompt = messages[-1]["content"] + context = convert(messages[:-1]) + + if not cookies: + for cookie in browser_cookie3.load(domain_name='.bing.com'): + cookies[cookie.name] = cookie.value + + return stream_generate(prompt, context, cookies) def convert(messages: list[dict[str, str]]): context = "" -- cgit v1.2.3 From 126496d3cacd06a4fa8cbb4e5bde417ce6bb5b4a Mon Sep 17 00:00:00 2001 From: Heiner Lohaus Date: Fri, 25 Aug 2023 06:41:32 +0200 Subject: Add OpenaiChat and Hugchat Provider Add tests for providers with auth Improve async support / 2x faster Shared get_cookies by domain function --- g4f/Provider/Bing.py | 86 +++++++++++++++++----------------------------------- 1 file changed, 28 insertions(+), 58 deletions(-) (limited to 'g4f/Provider/Bing.py') diff --git a/g4f/Provider/Bing.py b/g4f/Provider/Bing.py index b9b9e9a4..2c2e60ad 100644 --- a/g4f/Provider/Bing.py +++ b/g4f/Provider/Bing.py @@ -5,48 +5,24 @@ import random import aiohttp import asyncio -import browser_cookie3 from aiohttp import ClientSession from ..typing import Any, AsyncGenerator, CreateResult, Union -from .base_provider import BaseProvider +from .base_provider import AsyncGeneratorProvider, get_cookies -class Bing(BaseProvider): +class Bing(AsyncGeneratorProvider): url = "https://bing.com/chat" + needs_auth = True working = True supports_gpt_4 = True - - @classmethod - def create_completion( - cls, - model: str, - messages: list[dict[str, str]], - stream: bool, - **kwargs: Any - ) -> CreateResult: - if stream: - yield from run(cls.create_async_generator(model, messages, **kwargs)) - else: - yield asyncio.run(cls.create_async(model, messages, **kwargs)) - - @classmethod - async def create_async( - cls, - model: str, - messages: list[dict[str, str]], - **kwargs: Any, - ) -> str: - result = [] - async for chunk in cls.create_async_generator(model, messages, **kwargs): - result.append(chunk) - if result: - return "".join(result) + supports_stream=True @staticmethod def create_async_generator( model: str, messages: list[dict[str, str]], - cookies: dict = {} + cookies: dict = get_cookies(".bing.com"), + **kwargs ) -> AsyncGenerator: if len(messages) < 2: prompt = messages[0]["content"] @@ -54,15 +30,11 @@ class Bing(BaseProvider): else: prompt = messages[-1]["content"] - context = convert(messages[:-1]) - - if not cookies: - for cookie in browser_cookie3.load(domain_name='.bing.com'): - cookies[cookie.name] = cookie.value + context = create_context(messages[:-1]) return stream_generate(prompt, context, cookies) -def convert(messages: list[dict[str, str]]): +def create_context(messages: list[dict[str, str]]): context = "" for message in messages: @@ -187,34 +159,32 @@ class Defaults: 'x-forwarded-for': ip_address, } - optionsSets = { - "optionsSets": [ - 'saharasugg', - 'enablenewsfc', - 'clgalileo', - 'gencontentv3', - "nlu_direct_response_filter", - "deepleo", - "disable_emoji_spoken_text", - "responsible_ai_policy_235", - "enablemm", - "h3precise" - "dtappid", - "cricinfo", - "cricinfov2", - "dv3sugg", - "nojbfedge" - ] - } + optionsSets = [ + 'saharasugg', + 'enablenewsfc', + 'clgalileo', + 'gencontentv3', + "nlu_direct_response_filter", + "deepleo", + "disable_emoji_spoken_text", + "responsible_ai_policy_235", + "enablemm", + "h3precise" + "dtappid", + "cricinfo", + "cricinfov2", + "dv3sugg", + "nojbfedge" + ] -def format_message(msg: dict) -> str: - return json.dumps(msg, ensure_ascii=False) + Defaults.delimiter +def format_message(message: dict) -> str: + return json.dumps(message, ensure_ascii=False) + Defaults.delimiter def create_message(conversation: Conversation, prompt: str, context: str=None) -> str: struct = { 'arguments': [ { - **Defaults.optionsSets, + 'optionsSets': Defaults.optionsSets, 'source': 'cib', 'allowedMessageTypes': Defaults.allowedMessageTypes, 'sliceIds': Defaults.sliceIds, -- cgit v1.2.3 From efd75a11b871d61ac31b0e274acdfb33daba361d Mon Sep 17 00:00:00 2001 From: abc <98614666+xtekky@users.noreply.github.com> Date: Sun, 27 Aug 2023 17:37:44 +0200 Subject: ~ | code styling --- g4f/Provider/Bing.py | 27 ++++++++++----------------- 1 file changed, 10 insertions(+), 17 deletions(-) (limited to 'g4f/Provider/Bing.py') diff --git a/g4f/Provider/Bing.py b/g4f/Provider/Bing.py index 2c2e60ad..fe4f9a58 100644 --- a/g4f/Provider/Bing.py +++ b/g4f/Provider/Bing.py @@ -1,29 +1,22 @@ -import asyncio -import json -import os -import random +import asyncio, aiohttp, json, os, random -import aiohttp -import asyncio -from aiohttp import ClientSession - -from ..typing import Any, AsyncGenerator, CreateResult, Union +from aiohttp import ClientSession +from ..typing import Any, AsyncGenerator, CreateResult, Union from .base_provider import AsyncGeneratorProvider, get_cookies class Bing(AsyncGeneratorProvider): - url = "https://bing.com/chat" - needs_auth = True - working = True - supports_gpt_4 = True - supports_stream=True + url = "https://bing.com/chat" + needs_auth = True + working = True + supports_gpt_4 = True + supports_stream = True @staticmethod def create_async_generator( model: str, messages: list[dict[str, str]], - cookies: dict = get_cookies(".bing.com"), - **kwargs - ) -> AsyncGenerator: + cookies: dict = get_cookies(".bing.com"), **kwargs) -> AsyncGenerator: + if len(messages) < 2: prompt = messages[0]["content"] context = None -- cgit v1.2.3 From e2e2f281e8b64fadadcb3d36fac5faa1a4af20f2 Mon Sep 17 00:00:00 2001 From: Luneye <73485421+Luneye@users.noreply.github.com> Date: Sun, 27 Aug 2023 18:58:36 +0200 Subject: Update Bing.py Removed unnecessary check that could prematurely stop the AI's response while answering --- g4f/Provider/Bing.py | 122 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 76 insertions(+), 46 deletions(-) (limited to 'g4f/Provider/Bing.py') diff --git a/g4f/Provider/Bing.py b/g4f/Provider/Bing.py index 2c2e60ad..4056916e 100644 --- a/g4f/Provider/Bing.py +++ b/g4f/Provider/Bing.py @@ -8,33 +8,65 @@ import asyncio from aiohttp import ClientSession from ..typing import Any, AsyncGenerator, CreateResult, Union -from .base_provider import AsyncGeneratorProvider, get_cookies +from .base_provider import BaseProvider -class Bing(AsyncGeneratorProvider): +class Bing(BaseProvider): url = "https://bing.com/chat" - needs_auth = True - working = True supports_gpt_4 = True + working=True supports_stream=True - + @staticmethod - def create_async_generator( - model: str, - messages: list[dict[str, str]], - cookies: dict = get_cookies(".bing.com"), - **kwargs - ) -> AsyncGenerator: - if len(messages) < 2: - prompt = messages[0]["content"] - context = None - - else: - prompt = messages[-1]["content"] - context = create_context(messages[:-1]) - - return stream_generate(prompt, context, cookies) - -def create_context(messages: list[dict[str, str]]): + def create_completion( + model: str, + messages: list[dict[str, str]], + stream: bool, + **kwargs: Any + ) -> CreateResult: + yield from run(create(messages, **kwargs)) + +def create( + messages: list[dict[str, str]], + cookies: dict = {} + ): + if len(messages) < 2: + prompt = messages[0]["content"] + context = None + + else: + prompt = messages[-1]["content"] + context = convert(messages[:-1]) + + if not cookies: + cookies = { + 'MUID': '', + 'BCP': '', + 'MUIDB': '', + 'USRLOC': '', + 'SRCHD': 'AF=hpcodx', + 'MMCASM': '', + '_UR': '', + 'ANON': '', + 'NAP': '', + 'ABDEF': '', + 'PPLState': '1', + 'KievRPSSecAuth': '', + '_U': '', + 'SUID': '', + '_EDGE_S': '', + 'WLS': '', + '_HPVN': '', + '_SS': '', + '_clck': '', + 'SRCHUSR': '', + '_RwBf': '', + 'SRCHHPGUSR': '', + 'ipv6': '', + } + + return stream_generate(prompt, context, cookies) + +def convert(messages: list[dict[str, str]]): context = "" for message in messages: @@ -159,32 +191,34 @@ class Defaults: 'x-forwarded-for': ip_address, } - optionsSets = [ - 'saharasugg', - 'enablenewsfc', - 'clgalileo', - 'gencontentv3', - "nlu_direct_response_filter", - "deepleo", - "disable_emoji_spoken_text", - "responsible_ai_policy_235", - "enablemm", - "h3precise" - "dtappid", - "cricinfo", - "cricinfov2", - "dv3sugg", - "nojbfedge" - ] + optionsSets = { + "optionsSets": [ + 'saharasugg', + 'enablenewsfc', + 'clgalileo', + 'gencontentv3', + "nlu_direct_response_filter", + "deepleo", + "disable_emoji_spoken_text", + "responsible_ai_policy_235", + "enablemm", + "h3precise" + "dtappid", + "cricinfo", + "cricinfov2", + "dv3sugg", + "nojbfedge" + ] + } -def format_message(message: dict) -> str: - return json.dumps(message, ensure_ascii=False) + Defaults.delimiter +def format_message(msg: dict) -> str: + return json.dumps(msg, ensure_ascii=False) + Defaults.delimiter def create_message(conversation: Conversation, prompt: str, context: str=None) -> str: struct = { 'arguments': [ { - 'optionsSets': Defaults.optionsSets, + **Defaults.optionsSets, 'source': 'cib', 'allowedMessageTypes': Defaults.allowedMessageTypes, 'sliceIds': Defaults.sliceIds, @@ -264,10 +298,6 @@ async def stream_generate( response_txt += inline_txt + '\n' result_text += inline_txt + '\n' - if returned_text.endswith(' '): - final = True - break - if response_txt.startswith(returned_text): new = response_txt[len(returned_text):] if new != "\n": -- cgit v1.2.3 From 7294abc890c377d75c6c8c932620c2e2c8b3f0f9 Mon Sep 17 00:00:00 2001 From: Heiner Lohaus Date: Mon, 28 Aug 2023 01:43:45 +0200 Subject: Add async support for H2o Add format_prompt helper Fix create_completion in AsyncGeneratorProvider Move get_cookies from constructor to function Add ow HuggingChat implement Remove need auth form Liabots Add staic cache for access_token in OpenaiChat Add OpenAssistant provider Support stream and async in You Support async and add userId in Yqcloud Add log_time module --- g4f/Provider/Bing.py | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) (limited to 'g4f/Provider/Bing.py') diff --git a/g4f/Provider/Bing.py b/g4f/Provider/Bing.py index fe4f9a58..84be4212 100644 --- a/g4f/Provider/Bing.py +++ b/g4f/Provider/Bing.py @@ -15,8 +15,11 @@ class Bing(AsyncGeneratorProvider): def create_async_generator( model: str, messages: list[dict[str, str]], - cookies: dict = get_cookies(".bing.com"), **kwargs) -> AsyncGenerator: - + cookies: dict = None, + **kwargs + ) -> AsyncGenerator: + if not cookies: + cookies = get_cookies(".bing.com") if len(messages) < 2: prompt = messages[0]["content"] context = None @@ -273,15 +276,4 @@ async def stream_generate( final = True break finally: - await delete_conversation(session, conversation) - -def run(generator: AsyncGenerator[Union[Any, str], Any]): - loop = asyncio.get_event_loop() - gen = generator.__aiter__() - - while True: - try: - yield loop.run_until_complete(gen.__anext__()) - - except StopAsyncIteration: - break + await delete_conversation(session, conversation) \ No newline at end of file -- cgit v1.2.3 From 87c7db73a297b50e68ad7ca02673cfe749984841 Mon Sep 17 00:00:00 2001 From: Luneye <73485421+Luneye@users.noreply.github.com> Date: Mon, 28 Aug 2023 16:31:18 +0200 Subject: Update Bing.py Added support the async function Will implement proper cookie retrieval later but Bing is working for now --- g4f/Provider/Bing.py | 98 ++++++++++++++++++++++++---------------------------- 1 file changed, 45 insertions(+), 53 deletions(-) (limited to 'g4f/Provider/Bing.py') diff --git a/g4f/Provider/Bing.py b/g4f/Provider/Bing.py index 4056916e..4c7e0557 100644 --- a/g4f/Provider/Bing.py +++ b/g4f/Provider/Bing.py @@ -1,16 +1,11 @@ -import asyncio -import json -import os -import random +import asyncio, json, os, random, aiohttp -import aiohttp -import asyncio from aiohttp import ClientSession from ..typing import Any, AsyncGenerator, CreateResult, Union -from .base_provider import BaseProvider +from .base_provider import AsyncGeneratorProvider, get_cookies -class Bing(BaseProvider): +class Bing(AsyncGeneratorProvider): url = "https://bing.com/chat" supports_gpt_4 = True working=True @@ -20,53 +15,50 @@ class Bing(BaseProvider): def create_completion( model: str, messages: list[dict[str, str]], - stream: bool, - **kwargs: Any - ) -> CreateResult: - yield from run(create(messages, **kwargs)) - -def create( - messages: list[dict[str, str]], - cookies: dict = {} - ): - if len(messages) < 2: - prompt = messages[0]["content"] - context = None - - else: - prompt = messages[-1]["content"] - context = convert(messages[:-1]) - - if not cookies: - cookies = { - 'MUID': '', - 'BCP': '', - 'MUIDB': '', - 'USRLOC': '', - 'SRCHD': 'AF=hpcodx', - 'MMCASM': '', - '_UR': '', - 'ANON': '', - 'NAP': '', - 'ABDEF': '', - 'PPLState': '1', - 'KievRPSSecAuth': '', - '_U': '', - 'SUID': '', - '_EDGE_S': '', - 'WLS': '', - '_HPVN': '', - '_SS': '', - '_clck': '', - 'SRCHUSR': '', - '_RwBf': '', - 'SRCHHPGUSR': '', - 'ipv6': '', - } + cookies: dict = None, + **kwargs + ) -> AsyncGenerator: + + if len(messages) < 2: + prompt = messages[0]["content"] + context = None + + else: + prompt = messages[-1]["content"] + context = create_context(messages[:-1]) + if cookies is None: + #TODO: Will implement proper cookie retrieval later and use a try-except mechanism in 'stream_generate' instead of defaulting the cookie value like this + #cookies = get_cookies(".bing.com") + cookies = + { + 'MUID': '', + 'BCP': '', + 'MUIDB': '', + 'USRLOC': '', + 'SRCHD': 'AF=hpcodx', + 'MMCASM': '', + '_UR': '', + 'ANON': '', + 'NAP': '', + 'ABDEF': '', + 'PPLState': '1', + 'KievRPSSecAuth': '', + '_U': '', + 'SUID': '', + '_EDGE_S': '', + 'WLS': '', + '_HPVN': '', + '_SS': '', + '_clck': '', + 'SRCHUSR': '', + '_RwBf': '', + 'SRCHHPGUSR': '', + 'ipv6': '', + } - return stream_generate(prompt, context, cookies) + return stream_generate(prompt, context, cookies) -def convert(messages: list[dict[str, str]]): +def create_context(messages: list[dict[str, str]]): context = "" for message in messages: -- cgit v1.2.3 From a3851150b7b97cb7e9411f844634d6086473e837 Mon Sep 17 00:00:00 2001 From: Luneye <73485421+Luneye@users.noreply.github.com> Date: Mon, 28 Aug 2023 16:41:59 +0200 Subject: Update Bing.py Fixed some errors in my previously precipitated commit. --- g4f/Provider/Bing.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'g4f/Provider/Bing.py') diff --git a/g4f/Provider/Bing.py b/g4f/Provider/Bing.py index 4c7e0557..d96af6a6 100644 --- a/g4f/Provider/Bing.py +++ b/g4f/Provider/Bing.py @@ -10,12 +10,13 @@ class Bing(AsyncGeneratorProvider): supports_gpt_4 = True working=True supports_stream=True + needs_auth=True @staticmethod def create_completion( model: str, messages: list[dict[str, str]], - cookies: dict = None, + cookies: dict, **kwargs ) -> AsyncGenerator: @@ -26,11 +27,11 @@ class Bing(AsyncGeneratorProvider): else: prompt = messages[-1]["content"] context = create_context(messages[:-1]) - if cookies is None: + + if cookies: #TODO: Will implement proper cookie retrieval later and use a try-except mechanism in 'stream_generate' instead of defaulting the cookie value like this - #cookies = get_cookies(".bing.com") - cookies = - { + #cookies_dict = get_cookies(".bing.com") + cookies_dict = { 'MUID': '', 'BCP': '', 'MUIDB': '', @@ -55,8 +56,7 @@ class Bing(AsyncGeneratorProvider): 'SRCHHPGUSR': '', 'ipv6': '', } - - return stream_generate(prompt, context, cookies) + return stream_generate(prompt, context, cookies_dict) def create_context(messages: list[dict[str, str]]): context = "" -- cgit v1.2.3 From a4fe9907d613a6c81fb40491c7f3bfd766c7847f Mon Sep 17 00:00:00 2001 From: abc <98614666+xtekky@users.noreply.github.com> Date: Mon, 28 Aug 2023 21:13:47 +0100 Subject: ~ | v-0.0.2.6 --- g4f/Provider/Bing.py | 50 +++++++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 25 deletions(-) (limited to 'g4f/Provider/Bing.py') diff --git a/g4f/Provider/Bing.py b/g4f/Provider/Bing.py index 5910c6b4..c31ba5a7 100644 --- a/g4f/Provider/Bing.py +++ b/g4f/Provider/Bing.py @@ -15,9 +15,8 @@ class Bing(AsyncGeneratorProvider): def create_async_generator( model: str, messages: list[dict[str, str]], - cookies: dict = None, - **kwargs - ) -> AsyncGenerator: + cookies: dict = None, **kwargs) -> AsyncGenerator: + if not cookies: cookies = get_cookies(".bing.com") if len(messages) < 2: @@ -30,30 +29,31 @@ class Bing(AsyncGeneratorProvider): if cookies: #TODO: Will implement proper cookie retrieval later and use a try-except mechanism in 'stream_generate' instead of defaulting the cookie value like this cookies_dict = { - 'MUID': '', - 'BCP': '', - 'MUIDB': '', - 'USRLOC': '', - 'SRCHD': 'AF=hpcodx', - 'MMCASM': '', - '_UR': '', - 'ANON': '', - 'NAP': '', - 'ABDEF': '', - 'PPLState': '1', + 'MUID' : '', + 'BCP' : '', + 'MUIDB' : '', + 'USRLOC' : '', + 'SRCHD' : 'AF=hpcodx', + 'MMCASM' : '', + '_UR' : '', + 'ANON' : '', + 'NAP' : '', + 'ABDEF' : '', + 'PPLState' : '1', 'KievRPSSecAuth': '', - '_U': '', - 'SUID': '', - '_EDGE_S': '', - 'WLS': '', - '_HPVN': '', - '_SS': '', - '_clck': '', - 'SRCHUSR': '', - '_RwBf': '', - 'SRCHHPGUSR': '', - 'ipv6': '', + '_U' : '', + 'SUID' : '', + '_EDGE_S' : '', + 'WLS' : '', + '_HPVN' : '', + '_SS' : '', + '_clck' : '', + 'SRCHUSR' : '', + '_RwBf' : '', + 'SRCHHPGUSR' : '', + 'ipv6' : '', } + return stream_generate(prompt, context, cookies_dict) def create_context(messages: list[dict[str, str]]): -- cgit v1.2.3 From 3e6b1d6bef04881d8f46ab06331b5e3c5e2e3471 Mon Sep 17 00:00:00 2001 From: Heiner Lohaus Date: Fri, 1 Sep 2023 23:39:57 +0200 Subject: Set working=True in Liaobots, Fix bing provider, Update readme --- g4f/Provider/Bing.py | 21 ++------------------- 1 file changed, 2 insertions(+), 19 deletions(-) (limited to 'g4f/Provider/Bing.py') diff --git a/g4f/Provider/Bing.py b/g4f/Provider/Bing.py index c31ba5a7..48968e39 100644 --- a/g4f/Provider/Bing.py +++ b/g4f/Provider/Bing.py @@ -26,32 +26,15 @@ class Bing(AsyncGeneratorProvider): prompt = messages[-1]["content"] context = create_context(messages[:-1]) - if cookies: + if cookies and "SRCHD" in cookies: #TODO: Will implement proper cookie retrieval later and use a try-except mechanism in 'stream_generate' instead of defaulting the cookie value like this cookies_dict = { - 'MUID' : '', - 'BCP' : '', - 'MUIDB' : '', - 'USRLOC' : '', - 'SRCHD' : 'AF=hpcodx', - 'MMCASM' : '', - '_UR' : '', - 'ANON' : '', - 'NAP' : '', - 'ABDEF' : '', + 'SRCHD' : cookies["SRCHD"], 'PPLState' : '1', 'KievRPSSecAuth': '', - '_U' : '', 'SUID' : '', - '_EDGE_S' : '', - 'WLS' : '', - '_HPVN' : '', - '_SS' : '', - '_clck' : '', 'SRCHUSR' : '', - '_RwBf' : '', 'SRCHHPGUSR' : '', - 'ipv6' : '', } return stream_generate(prompt, context, cookies_dict) -- cgit v1.2.3 From 901595b10f08972ee3ac5fc08c346dbb561a7d62 Mon Sep 17 00:00:00 2001 From: msi-JunXiang Date: Sun, 3 Sep 2023 16:26:26 +0800 Subject: type hints Use `from __future__ import annotations avoid `dict` and `list` cause "TypeErro: 'type' object is not subscriptable". Refer to the following Stack Overflow discussions for more information: 1. https://stackoverflow.com/questions/75202610/typeerror-type-object-is-not-subscriptable-python 2. https://stackoverflow.com/questions/59101121/type-hint-for-a-dict-gives-typeerror-type-object-is-not-subscriptable --- g4f/Provider/Bing.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'g4f/Provider/Bing.py') diff --git a/g4f/Provider/Bing.py b/g4f/Provider/Bing.py index 48968e39..57dfcec9 100644 --- a/g4f/Provider/Bing.py +++ b/g4f/Provider/Bing.py @@ -1,9 +1,17 @@ -import asyncio, aiohttp, json, os, random +from __future__ import annotations -from aiohttp import ClientSession -from ..typing import Any, AsyncGenerator, CreateResult, Union +import asyncio +import json +import os +import random + +import aiohttp +from aiohttp import ClientSession + +from ..typing import Any, AsyncGenerator, CreateResult, Union from .base_provider import AsyncGeneratorProvider, get_cookies + class Bing(AsyncGeneratorProvider): url = "https://bing.com/chat" needs_auth = True -- cgit v1.2.3 From 17c9adf4852a0ca0d1a5cfa448478fa195a9c368 Mon Sep 17 00:00:00 2001 From: hs_junxiang Date: Mon, 4 Sep 2023 13:34:31 +0800 Subject: Join the messages A better approach is to use the `.join()` method of strings, which reduces string concatenation operations and improves performance. Additionally, using formatted strings (f-strings) makes the code cleaner and more readable. --- g4f/Provider/Bing.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'g4f/Provider/Bing.py') diff --git a/g4f/Provider/Bing.py b/g4f/Provider/Bing.py index 48968e39..1642877d 100644 --- a/g4f/Provider/Bing.py +++ b/g4f/Provider/Bing.py @@ -40,10 +40,7 @@ class Bing(AsyncGeneratorProvider): return stream_generate(prompt, context, cookies_dict) def create_context(messages: list[dict[str, str]]): - context = "" - - for message in messages: - context += "[%s](#message)\n%s\n\n" % (message["role"], message["content"]) + context = "".join(f"[{message['role']}](#message)\n{message['content']}\n\n" for message in messages) return context -- cgit v1.2.3