diff --git a/main.py b/main.py index 493d39c..9151255 100644 --- a/main.py +++ b/main.py @@ -4,6 +4,8 @@ import time import random import string import json +import re +from urllib.parse import urlparse PORT = 8081 HOST = "127.0.0.1" @@ -114,6 +116,7 @@ class SSEHandler(web.View): return print("Ошибка запуска чатбота.", str(e)) return + end_data = { "id": self.id, "object": "chat.completion.chunk", @@ -145,8 +148,14 @@ class SSEHandler(web.View): } async def output(): + print("\nФормируется запрос...") + non_stream_response = "" + placeholder_wrap = "" + placeholder_flag = False + got_number = False wrote = 0 + async for final, response in chatbot.ask_stream( prompt=prompt, raw=True, @@ -158,9 +167,24 @@ class SSEHandler(web.View): if not final and response["type"] == 1 and "messages" in response["arguments"][0]: message = response["arguments"][0]["messages"][0] match message.get("messageType"): + case "InternalSearchQuery": + print(f"Поиск в Бинге:\n{message['hiddenText']}\n\n") + case "InternalSearchResult": + if 'hiddenText' in message: + search = message['hiddenText'] = message['hiddenText'][len("```json\n"):] + search = search[:-len("```")] + search = json.loads(search) + urls = [] + if "question_answering_results" in search: + for result in search["question_answering_results"]: + urls.append(result["url"]) + + if "web_search_results" in search: + for result in search["web_search_results"]: + urls.append(result["url"]) case None: if "cursor" in response["arguments"][0]: - print("Ответ от сервера:\n") + print("\nОтвет от сервера:\n") wrote = 0 if message.get("contentOrigin") == "Apology": if stream and wrote == 0: @@ -181,30 +205,65 @@ class SSEHandler(web.View): print("\nСообщение отозвано.") break else: - data = { - "id": self.id, - "object": "chat.completion.chunk", - "created": self.created, - "model": "gpt-4", - "choices": [ - { - "delta": { - "content": message['text'][wrote:] - }, - "index": 0, - "finish_reason": "null" - } - ] - } if stream: - await self.response.write(prepare_response(data)) + def replace_with_array(match): + index = int(match.group(1)) - 1 + return f" [{urlparse(urls[index]).hostname}]({urls[index]})" + + content = message['text'][wrote:] + placeholder_number = r'\^(\d+)\^' + + if got_number: + placeholder_flag = False + if not re.findall(']', content): + content = placeholder_wrap + content + else: + content = placeholder_wrap + got_number = False + if content == "[": + placeholder_flag = True + number_matches = re.findall(placeholder_number, content) + + if number_matches: + if placeholder_flag: + placeholder_wrap = re.sub(placeholder_number, + replace_with_array, + message['text'][wrote:] + ) + got_number = True + else: + content = re.sub(placeholder_number, + replace_with_array, + message['text'][wrote:] + ) + + if not placeholder_flag: + data = { + "id": self.id, + "object": "chat.completion.chunk", + "created": self.created, + "model": "gpt-4", + "choices": [ + { + "delta": { + "content": content + }, + "index": 0, + "finish_reason": "null" + } + ] + } + + await self.response.write(prepare_response(data)) else: non_stream_response += message['text'][wrote:] + print(message["text"][wrote:], end="") wrote = len(message["text"]) + if "suggestedResponses" in message: + print(message) suggested_responses = '\n'.join(x["text"] for x in message["suggestedResponses"]) - #suggested_responses = "\n```\n" + suggested_responses + "\n```" suggested_responses = "\n```" + suggested_responses + "```" if stream: data = { @@ -227,6 +286,20 @@ class SSEHandler(web.View): else: await self.response.write(prepare_response(end_data, "DONE")) else: + #will fix the duplication later + def replace_with_array(match): + index = int(match.group(1)) - 1 + return f" [{urlparse(urls[index]).hostname}]({urls[index]})" + + placeholder_number = r'\[\^(\d+)\^\]' + number_matches = re.findall(placeholder_number, non_stream_response) + + if number_matches: + non_stream_response = re.sub(placeholder_number, + replace_with_array, + non_stream_response + ) + if suggestion: non_stream_response = non_stream_response + suggested_responses await self.response.write( @@ -243,19 +316,16 @@ class SSEHandler(web.View): if stream: await self.response.write(prepare_response(filtered_data, end_data)) print("Сработал фильтр.") - + await chatbot.close() try: await output() except Exception as e: - if(str(e) == "'messages'"): + if str(e) == "'messages'": print("Ошибка:", str(e), "\nПроблема с учеткой. Либо забанили, либо нужно залогиниться.") - if(str(e) == " " or str(e) == ""): + if str(e) == " " or str(e) == "": print("Таймаут.") else: print("Ошибка: ", str(e)) - await chatbot.close() - - return self.response app = web.Application() @@ -269,5 +339,5 @@ if __name__ == '__main__': f"Режим creative: http://{HOST}:{PORT}/creative\n" f"Режим precise: http://{HOST}:{PORT}/precise\n" f"Режим balanced: http://{HOST}:{PORT}/balanced\n" - f"Также есть режим подсказок. Чтобы его включить, нужно добавить /suggestion к концу URL.") + f"Также есть режим подсказок от Бинга. Чтобы его включить, нужно добавить /suggestion к концу URL, после режима.") web.run_app(app, host=HOST, port=PORT, print=None)