Add files via upload
This commit is contained in:
parent
66a32b6843
commit
ec147ca3f2
11
README.md
11
README.md
|
@ -5,17 +5,18 @@
|
||||||
|
|
||||||
## Что можно?
|
## Что можно?
|
||||||
Смут.</br>
|
Смут.</br>
|
||||||
14к токенов (лично у меня 32к не схавал).</br>
|
По слованом анона 16-20к токенов.</br>
|
||||||
Кодинг с рабочим стримом (плюс в сравнении со скалой).</br>
|
Кодинг с рабочим стримом (плюс в сравнении со скалой).</br>
|
||||||
Подтягивать данные из интернета.</br></br>
|
Подтягивать данные из интернета.</br></br>
|
||||||
![image](https://github.com/Barbariskaa/Biba/assets/129290831/b5176621-4a1f-4b57-9c7f-865861825c30)</br></br>
|
![image](https://github.com/Barbariskaa/Biba/assets/129290831/b5176621-4a1f-4b57-9c7f-865861825c30)</br></br>
|
||||||
Подтягивать подсказки из бинга.</br></br>
|
Подтягивать подсказки из бинга (через /suggestion после указанного в URL режима).</br></br>
|
||||||
![image](https://user-images.githubusercontent.com/129290831/236729981-42f4cbf8-abbd-4deb-9a70-1a1cb5917119.png)
|
![image](https://user-images.githubusercontent.com/129290831/236729981-42f4cbf8-abbd-4deb-9a70-1a1cb5917119.png)
|
||||||
|
|
||||||
## Что по куму?
|
## Что по куму?
|
||||||
Ответы с сервера фильтруются посреди стрима, прямо как в чае. В среднем обрубает на 100 токенах и до нескольких сотен. Зависит от выбранного режима.<br>
|
Ответы с сервера фильтруются посреди стрима, прямо как в чае. В среднем обрубает на 100 токенах и до нескольких сотен. Зависит от выбранного режима.<br>
|
||||||
Возможно это ограничение можно обойти, если повозиться с промптами.</br>
|
Возможно это ограничение можно обойти, если повозиться с промптами.</br>
|
||||||
Также банят. Могут забанить за один день, в отличии от Слаки. Решается перерегом.
|
Также банят. Могут забанить за один день, в отличии от Слаки. Решается перерегом.</br>
|
||||||
|
С 29.05.2023г. на территории РФ работает только через VPN.
|
||||||
|
|
||||||
## Как поставить?
|
## Как поставить?
|
||||||
Нужны куки чата с Бингом.<br>
|
Нужны куки чата с Бингом.<br>
|
||||||
|
@ -24,8 +25,8 @@
|
||||||
|
|
||||||
Если установлен не Windows с Эджем, то придется повозиться с юзерагентом. Можно поставить следующий ЮА:</br> `Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36 Edg/111.0.1661.51`</br></br>
|
Если установлен не Windows с Эджем, то придется повозиться с юзерагентом. Можно поставить следующий ЮА:</br> `Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36 Edg/111.0.1661.51`</br></br>
|
||||||
Также, санкционным анонам придется повозиться с доступом к Бингу. Рекомендую использовать впн и чистить куки, затем искать в самом бинге Bing AI. Если нет кнопки перехода в чат, значит нужно либо чистить куки еще раз, либо пробовать другой айпи впна.</br></br>
|
Также, санкционным анонам придется повозиться с доступом к Бингу. Рекомендую использовать впн и чистить куки, затем искать в самом бинге Bing AI. Если нет кнопки перехода в чат, значит нужно либо чистить куки еще раз, либо пробовать другой айпи впна.</br></br>
|
||||||
![image](https://user-images.githubusercontent.com/129290831/236732426-91d87aa3-32e2-4f87-9758-ac5c4b222a71.png)
|
![image](https://user-images.githubusercontent.com/129290831/236732426-91d87aa3-32e2-4f87-9758-ac5c4b222a71.png) </br>
|
||||||
|
Ссылка на чат по которой доступен Бинг в случае успешной настройки: https://www.bing.com/search?q=Bing+AI&showconv=1&wlsso=0 </br>
|
||||||
|
|
||||||
После успешного захода и открытия чата, нужно экспортировать сами куки. Для этого нужен следующий плагин:
|
После успешного захода и открытия чата, нужно экспортировать сами куки. Для этого нужен следующий плагин:
|
||||||
* Хром/Эдж: https://chrome.google.com/webstore/detail/cookie-editor/hlkenndednhfkekhgcdicdfddnkalmdm
|
* Хром/Эдж: https://chrome.google.com/webstore/detail/cookie-editor/hlkenndednhfkekhgcdicdfddnkalmdm
|
||||||
|
|
243
main.py
243
main.py
|
@ -12,11 +12,11 @@ from urllib.parse import urlparse
|
||||||
PORT = 8081
|
PORT = 8081
|
||||||
HOST = "127.0.0.1"
|
HOST = "127.0.0.1"
|
||||||
|
|
||||||
CONCATENATE_NSFW_RESPONSES = True
|
CONCATENATE_RESPONSES = True
|
||||||
DESIRED_TOKENS = 500
|
CONCATENATE_RESPONSES_STRING = "\n\n"
|
||||||
ASK_TO_CONTINUE_AS_A_ROLE = "user" #user/system/assistant
|
DESIRED_TOKENS = 200
|
||||||
CONTINUATION_QUERY = "(continue roleplay from the sentence where you have left)"
|
CONTINUATION_QUERY = "(continue roleplay from the sentence where you have left)"
|
||||||
ASTERISK_FIX = True
|
MARKUP_FIX = True
|
||||||
|
|
||||||
USER_MESSAGE_WORKAROUND = True
|
USER_MESSAGE_WORKAROUND = True
|
||||||
USER_MESSAGE = "Respond to the text above."
|
USER_MESSAGE = "Respond to the text above."
|
||||||
|
@ -44,12 +44,16 @@ class LinkPlaceholderReplacer:
|
||||||
return ""
|
return ""
|
||||||
elif self.i == 1 and not re.search(self.regex, self.stash):
|
elif self.i == 1 and not re.search(self.regex, self.stash):
|
||||||
self.i = 0
|
self.i = 0
|
||||||
return self.stash
|
result = self.stash
|
||||||
|
self.stash = ""
|
||||||
|
return result
|
||||||
elif self.i == 2:
|
elif self.i == 2:
|
||||||
result = re.sub(r'\[\^(\d+)\^\]', lambda match: transform_into_hyperlink(match, urls), self.stash)
|
result = re.sub(r'\[\^(\d+)\^\]', lambda match: transform_into_hyperlink(match, urls), self.stash)
|
||||||
self.i = 0
|
self.i = 0
|
||||||
self.stash = ""
|
self.stash = ""
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
self.stash = ""
|
||||||
|
|
||||||
|
|
||||||
class OpenaiResponse:
|
class OpenaiResponse:
|
||||||
|
@ -157,8 +161,31 @@ class SSEHandler(web.View):
|
||||||
return web.json_response(data)
|
return web.json_response(data)
|
||||||
|
|
||||||
async def post(self):
|
async def post(self):
|
||||||
id = "chatcmpl-" + ''.join(random.choices(string.ascii_letters + string.digits, k=29))
|
|
||||||
created = str(int(time.time()))
|
self.id = "chatcmpl-" + ''.join(random.choices(string.ascii_letters + string.digits, k=29))
|
||||||
|
self.created = str(int(time.time()))
|
||||||
|
self.responseWasFiltered = False
|
||||||
|
self.responseWasFilteredInLoop = False
|
||||||
|
self.response_text = ""
|
||||||
|
self.full_response = ""
|
||||||
|
|
||||||
|
async def streamCallback(self, data):
|
||||||
|
self.full_response += data
|
||||||
|
if stream:
|
||||||
|
await self.response.write(b"data: " + json.dumps({
|
||||||
|
"id": self.id,
|
||||||
|
"object": "chat.completion.chunk",
|
||||||
|
"created": self.created,
|
||||||
|
"model": "gpt-4",
|
||||||
|
"choices": [
|
||||||
|
{
|
||||||
|
"delta": { "content": data },
|
||||||
|
"index": 0,
|
||||||
|
"finish_reason": "null"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}).encode() + b"\n\n")
|
||||||
|
|
||||||
request_data = await self.request.json()
|
request_data = await self.request.json()
|
||||||
|
|
||||||
messages = request_data.get('messages', [])
|
messages = request_data.get('messages', [])
|
||||||
|
@ -169,22 +196,14 @@ class SSEHandler(web.View):
|
||||||
prompt = messages[-1]['content']
|
prompt = messages[-1]['content']
|
||||||
context = process_messages(messages[:-1])
|
context = process_messages(messages[:-1])
|
||||||
stream = request_data.get('stream', [])
|
stream = request_data.get('stream', [])
|
||||||
if stream:
|
self.response = web.StreamResponse(
|
||||||
self.response = web.StreamResponse(
|
status=200,
|
||||||
status=200,
|
headers={
|
||||||
headers={
|
'Content-Type': 'application/json',
|
||||||
'Content-Type': 'application/json',
|
}
|
||||||
}
|
)
|
||||||
)
|
await self.response.prepare(self.request)
|
||||||
await self.response.prepare(self.request)
|
|
||||||
else:
|
|
||||||
self.response = web.StreamResponse(
|
|
||||||
status=200,
|
|
||||||
headers={
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
}
|
|
||||||
)
|
|
||||||
await self.response.prepare(self.request)
|
|
||||||
|
|
||||||
conversation_style = self.request.path.split('/')[1]
|
conversation_style = self.request.path.split('/')[1]
|
||||||
if conversation_style not in ["creative", "balanced", "precise"]:
|
if conversation_style not in ["creative", "balanced", "precise"]:
|
||||||
|
@ -193,20 +212,21 @@ class SSEHandler(web.View):
|
||||||
suggestion = self.request.path.split('/')[2]
|
suggestion = self.request.path.split('/')[2]
|
||||||
if suggestion != "suggestion":
|
if suggestion != "suggestion":
|
||||||
suggestion = None
|
suggestion = None
|
||||||
try:
|
|
||||||
chatbot = await Chatbot.create(cookie_path="cookies.json")
|
async def output(self, streamCallback, nsfwMode=False):
|
||||||
except Exception as e:
|
self.response_text = ""
|
||||||
if str(e) == "[Errno 11001] getaddrinfo failed":
|
|
||||||
print("Нет интернет соединения.")
|
try:
|
||||||
|
chatbot = await Chatbot.create(cookie_path="cookies.json")
|
||||||
|
except Exception as e:
|
||||||
|
if str(e) == "[Errno 11001] getaddrinfo failed":
|
||||||
|
print("Нет интернет-соединения.")
|
||||||
|
return
|
||||||
|
print("Ошибка запуска чатбота.", str(e))
|
||||||
return
|
return
|
||||||
print("Ошибка запуска чатбота.", str(e))
|
|
||||||
return
|
|
||||||
|
|
||||||
async def output():
|
|
||||||
print("\nФормируется запрос...")
|
print("\nФормируется запрос...")
|
||||||
|
|
||||||
link_placeholder_replacer = LinkPlaceholderReplacer()
|
link_placeholder_replacer = LinkPlaceholderReplacer()
|
||||||
response_text = ""
|
|
||||||
wrote = 0
|
wrote = 0
|
||||||
|
|
||||||
async for final, response in chatbot.ask_stream(
|
async for final, response in chatbot.ask_stream(
|
||||||
|
@ -240,20 +260,22 @@ class SSEHandler(web.View):
|
||||||
print("\nОтвет от сервера:\n")
|
print("\nОтвет от сервера:\n")
|
||||||
if message.get("contentOrigin") == "Apology":
|
if message.get("contentOrigin") == "Apology":
|
||||||
if stream and wrote == 0:
|
if stream and wrote == 0:
|
||||||
await self.response.write(prepare_response(id, created, filter=True))
|
await streamCallback(self, "Отфильтровано.")
|
||||||
|
if nsfwMode:
|
||||||
|
self.responseWasFilteredInLoop = True
|
||||||
|
break
|
||||||
|
|
||||||
if stream:
|
if MARKUP_FIX:
|
||||||
if ASTERISK_FIX and (response_text.count("*") % 2 == 1):
|
if self.response_text.count("*") % 2 == 1 or self.response_text.count("*") == 1:
|
||||||
asterisk = "*"
|
await streamCallback(self, "*")
|
||||||
else:
|
self.response_text += "*"
|
||||||
asterisk = ""
|
if self.response_text.count("\"") % 2 == 1 or self.response_text.count("\"") == 1:
|
||||||
await self.response.write(prepare_response(id, created, content=asterisk, end=True, done=True))
|
await streamCallback(self, "\"")
|
||||||
else:
|
self.response_text += "\""
|
||||||
if ASTERISK_FIX and len(response_text.split("*")) % 2 == 0:
|
|
||||||
response_text += "*"
|
self.responseWasFiltered = True
|
||||||
oai_response = prepare_response(id, created, content=response_text, stream=False)
|
|
||||||
await self.response.write(oai_response)
|
print("\nОтвет отозван во время стрима.")
|
||||||
print("\nСообщение отозвано.")
|
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
streaming_content_chunk = message['text'][wrote:]
|
streaming_content_chunk = message['text'][wrote:]
|
||||||
|
@ -264,10 +286,9 @@ class SSEHandler(web.View):
|
||||||
if urls:
|
if urls:
|
||||||
streaming_content_chunk = link_placeholder_replacer.process(streaming_content_chunk, urls)
|
streaming_content_chunk = link_placeholder_replacer.process(streaming_content_chunk, urls)
|
||||||
|
|
||||||
response_text += streaming_content_chunk
|
self.response_text += streaming_content_chunk
|
||||||
|
|
||||||
if stream:
|
await streamCallback(self, streaming_content_chunk)
|
||||||
await self.response.write(prepare_response(id, created, content=streaming_content_chunk))
|
|
||||||
|
|
||||||
print(message["text"][wrote:], end="")
|
print(message["text"][wrote:], end="")
|
||||||
sys.stdout.flush()
|
sys.stdout.flush()
|
||||||
|
@ -276,30 +297,97 @@ class SSEHandler(web.View):
|
||||||
if "suggestedResponses" in message:
|
if "suggestedResponses" in message:
|
||||||
suggested_responses = '\n'.join(x["text"] for x in message["suggestedResponses"])
|
suggested_responses = '\n'.join(x["text"] for x in message["suggestedResponses"])
|
||||||
suggested_responses = "\n```" + suggested_responses + "```"
|
suggested_responses = "\n```" + suggested_responses + "```"
|
||||||
if stream:
|
if suggestion and not nsfwMode:
|
||||||
if suggestion:
|
await streamCallback(self, suggested_responses)
|
||||||
await self.response.write(prepare_response(id, created, content=streaming_content_chunk, end=True, done=True))
|
|
||||||
else:
|
|
||||||
await self.response.write(prepare_response(id, created, end=True, done=True))
|
|
||||||
else:
|
|
||||||
if suggestion:
|
|
||||||
response_text = response_text + suggested_responses
|
|
||||||
oai_response = prepare_response(id, created, content=response_text, stream=False)
|
|
||||||
await self.response.write(oai_response)
|
|
||||||
break
|
break
|
||||||
if final and not response["item"]["messages"][-1].get("text"):
|
if final and not response["item"]["messages"][-1].get("text"):
|
||||||
if stream:
|
|
||||||
await self.response.write(prepare_response(id, created, filter=True, end=True))
|
|
||||||
print("Сработал фильтр.")
|
print("Сработал фильтр.")
|
||||||
|
if nsfwMode:
|
||||||
|
print("Выходим из цикла.\n")
|
||||||
|
self.responseWasFilteredInLoop = True
|
||||||
|
|
||||||
if response_text:
|
|
||||||
encoding = tiktoken.get_encoding("cl100k_base")
|
|
||||||
tokens = len(encoding.encode(response_text))
|
|
||||||
print(f"\nВсего токенов в ответе: \033[1;32m{tokens}\033[0m")
|
|
||||||
|
|
||||||
try:
|
|
||||||
await output()
|
|
||||||
await chatbot.close()
|
await chatbot.close()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
if stream:
|
||||||
|
await self.response.write(b"data: " + json.dumps({
|
||||||
|
"id": self.id,
|
||||||
|
"object": "chat.completion.chunk",
|
||||||
|
"created": self.created,
|
||||||
|
"model": "gpt-4",
|
||||||
|
"choices": [
|
||||||
|
{
|
||||||
|
"delta": { "role": 'assistant' },
|
||||||
|
"index": 0,
|
||||||
|
"finish_reason": "null"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}).encode() + b"\n\n")
|
||||||
|
await output(self, streamCallback)
|
||||||
|
encoding = tiktoken.get_encoding("cl100k_base")
|
||||||
|
if self.responseWasFiltered and CONCATENATE_RESPONSES:
|
||||||
|
tokens_total = len(encoding.encode(self.full_response))
|
||||||
|
if USER_MESSAGE_WORKAROUND:
|
||||||
|
prompt = CONTINUATION_QUERY
|
||||||
|
context += f"[assistant](#message)\n{self.response_text}\n"
|
||||||
|
else:
|
||||||
|
context+=f"[{messages[-1]['role']}](#message)\n{prompt}\n\n[assistant](#message)\n{self.response_text}\n"
|
||||||
|
prompt=CONTINUATION_QUERY
|
||||||
|
self.full_response += CONCATENATE_RESPONSES_STRING
|
||||||
|
print("Токенов в ответе:",tokens_total)
|
||||||
|
while tokens_total < DESIRED_TOKENS and not self.responseWasFilteredInLoop:
|
||||||
|
if stream:
|
||||||
|
await self.response.write(b"data: " + json.dumps({
|
||||||
|
"id": self.id,
|
||||||
|
"object": "chat.completion.chunk",
|
||||||
|
"created": self.created,
|
||||||
|
"model": "gpt-4",
|
||||||
|
"choices": [
|
||||||
|
{
|
||||||
|
"delta": { "content": CONCATENATE_RESPONSES_STRING },
|
||||||
|
"index": 0,
|
||||||
|
"finish_reason": "null"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}).encode() + b"\n\n")
|
||||||
|
await output(self, streamCallback, nsfwMode=True)
|
||||||
|
context+=self.response_text + CONCATENATE_RESPONSES_STRING
|
||||||
|
self.full_response += CONCATENATE_RESPONSES_STRING
|
||||||
|
tokens_response = len(encoding.encode(self.response_text))
|
||||||
|
tokens_total = len(encoding.encode(self.full_response))
|
||||||
|
print(f"Токенов в ответе: {tokens_response}")
|
||||||
|
print(f"Токенов всего: {tokens_total}")
|
||||||
|
|
||||||
|
if stream:
|
||||||
|
await self.response.write(b"data: " + json.dumps({
|
||||||
|
"id": self.id,
|
||||||
|
"created": self.created,
|
||||||
|
"object": 'chat.completion.chunk',
|
||||||
|
"model": "gpt-4",
|
||||||
|
"choices": [{
|
||||||
|
"delta": {},
|
||||||
|
"finish_reason": 'stop',
|
||||||
|
"index": 0,
|
||||||
|
}],
|
||||||
|
}).encode() + b"\n\n")
|
||||||
|
else:
|
||||||
|
await self.response.write(json.dumps({
|
||||||
|
"id": self.id,
|
||||||
|
"created": self.created,
|
||||||
|
"object": "chat.completion",
|
||||||
|
"model": "gpt-4",
|
||||||
|
"choices": [{
|
||||||
|
"message": {
|
||||||
|
"role": 'assistant',
|
||||||
|
"content": self.full_response
|
||||||
|
},
|
||||||
|
'finish_reason': 'stop',
|
||||||
|
'index': 0,
|
||||||
|
}]
|
||||||
|
}).encode())
|
||||||
|
return self.response
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
error = f"Ошибка: {str(e)}."
|
error = f"Ошибка: {str(e)}."
|
||||||
error_text = ""
|
error_text = ""
|
||||||
|
@ -324,12 +412,19 @@ class SSEHandler(web.View):
|
||||||
print(error, error_text)
|
print(error, error_text)
|
||||||
else:
|
else:
|
||||||
print(error)
|
print(error)
|
||||||
if stream:
|
if not self.full_response:
|
||||||
oai_response = prepare_response(id, created, content=error + error_text, end=True, done=True, stream=True)
|
if stream:
|
||||||
|
oai_response = prepare_response(self.id, self.created, content=error + error_text, end=True, done=True, stream=True)
|
||||||
|
else:
|
||||||
|
oai_response = prepare_response(self.id, self.created, content=error + error_text, stream=False)
|
||||||
else:
|
else:
|
||||||
oai_response = prepare_response(id, created, content=error + error_text, stream=False)
|
if stream:
|
||||||
|
oai_response = prepare_response(self.id, self.created, end=True, done=True, stream=True)
|
||||||
|
else:
|
||||||
|
oai_response = prepare_response(self.id, self.created, content=self.full_response, stream=False)
|
||||||
await self.response.write(oai_response)
|
await self.response.write(oai_response)
|
||||||
return self.response
|
return self.response
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
app = web.Application()
|
app = web.Application()
|
||||||
|
@ -344,4 +439,4 @@ if __name__ == '__main__':
|
||||||
f"Режим precise: http://{HOST}:{PORT}/precise\n"
|
f"Режим precise: http://{HOST}:{PORT}/precise\n"
|
||||||
f"Режим balanced: http://{HOST}:{PORT}/balanced\n"
|
f"Режим balanced: http://{HOST}:{PORT}/balanced\n"
|
||||||
f"Также есть режим подсказок от Бинга. Чтобы его включить, нужно добавить /suggestion к концу URL, после режима.")
|
f"Также есть режим подсказок от Бинга. Чтобы его включить, нужно добавить /suggestion к концу URL, после режима.")
|
||||||
web.run_app(app, host=HOST, port=PORT, print=None)
|
web.run_app(app, host=HOST, port=PORT, print=None)
|
Loading…
Reference in New Issue