Skip to content

Commit

Permalink
Merge pull request #48 from RockChinQ/new-bing
Browse files Browse the repository at this point in the history
[Feat] 支持new bing
  • Loading branch information
RockChinQ authored Mar 15, 2023
2 parents a0adacd + fe6eff9 commit f9834cb
Show file tree
Hide file tree
Showing 9 changed files with 147 additions and 12 deletions.
34 changes: 33 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,36 @@
`QChatGPT`程序目录编辑`revcfg.py`文件,根据注释修改必填配置项。
配置完成后重新启动主程序以使用。

### **❗注意:由于此接口响应较慢,请在主程序`config.py`中将`process_message_timeout`字段设置为300以上**
## 更换逆向库

目前支持的逆向库及使用方式如下:

<details>
<summary>ChatGPT网页版</summary>

使用的是 [acheong08/ChatGPT](https://github.com/acheong08/ChatGPT)
本插件默认使用的逆向库,使用方法请参考上方文档及配置文件注释。

</details>

<details>
<summary>New Bing</summary>

使用的是 [acheong08/EdgeGPT](https://github.com/acheong08/EdgeGPT)

- 修改`revcfg.py`中的`reverse_lib``acheong08/EdgeGPT`
- 安装适用于[Chrome/Edge](https://chrome.google.com/webstore/detail/cookie-editor/hlkenndednhfkekhgcdicdfddnkalmdm)[Firefox](https://addons.mozilla.org/en-US/firefox/addon/cookie-editor/) 的Cookies编辑器插件
- 访问 `bing.com`
- 打开这个插件
- 点击 `Export` 按钮, 复制JSON格式的Cookies
- 在QChatGPT主程序`main.py`同目录下新建文件`cookies.json`, 将刚才复制的内容粘贴进去

#### 配置

new bing逆向库默认输出参考资料, 若不需要, 请在`revcfg.py`中设置:

```python
output_references = False
```

</details>
19 changes: 14 additions & 5 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,22 @@ def __init__(self, plugin_host: PluginHost):
import revcfg

try:
import plugins.revLibs.pkg.process.impls.v1impl as v1impl
if revcfg.reverse_lib == "acheong08/ChatGPT.V1":
import plugins.revLibs.pkg.process.impls.v1impl as v1impl

v1implInst = v1impl.RevChatGPTV1
v1implInst = v1impl.RevChatGPTV1

import plugins.revLibs.pkg.process.revss as revss
revss.__rev_interface_impl_class__ = v1implInst

elif revcfg.reverse_lib == "acheong08/EdgeGPT":
import plugins.revLibs.pkg.process.impls.edgegpt as edgegpt

edgegptInst = edgegpt.EdgeGPTImpl

import plugins.revLibs.pkg.process.revss as revss
revss.__rev_interface_impl_class__ = edgegptInst

import plugins.revLibs.pkg.process.revss as revss
revss.__rev_interface_impl_class__ = v1implInst
# plugin_host.notify_admin("[rev] 逆向库初始化成功")
logging.info("[rev] 逆向库初始化成功")
except:
# 输出完整的错误信息
Expand Down
8 changes: 4 additions & 4 deletions pkg/models/interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@
class RevLibInterface:
"""逆向库接口"""

def get_rev_lib_inst():
def get_rev_lib_inst(self):
raise NotImplementedError

def get_reply(prompt: str, **kwargs) -> Tuple[str, dict]:
def get_reply(self, prompt: str, **kwargs) -> Tuple[str, dict]:
raise NotImplementedError

def reset_chat():
def reset_chat(self, **kwargs):
raise NotImplementedError

def rollback():
def rollback(self):
raise NotImplementedError
77 changes: 77 additions & 0 deletions pkg/process/impls/edgegpt.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
"""接入acheone08/EdgeGPT
"""
import os
import logging
import json
import asyncio

from plugins.revLibs.pkg.models.interface import RevLibInterface
from EdgeGPT import Chatbot, ConversationStyle


class EdgeGPTImpl(RevLibInterface):
"""使用acheong08/EdgeGPT接入new bing
"""
chatbot: Chatbot = None

style = ConversationStyle.creative

inst_name: str

@staticmethod
def create_instance() -> tuple[RevLibInterface, bool, dict]:
# 检查new bing的cookies是否存在
if not os.path.exists("cookies.json"):
logging.error("new bing cookies不存在")
raise Exception("new bing cookies不存在, 请根据文档进行配置")

cookies_dict = {}
with open("cookies.json", "r", encoding="utf-8") as f:
cookies_dict = json.load(f)

return EdgeGPTImpl(cookies_dict, ConversationStyle.creative), True, cookies_dict

def __init__(self, cookies, style):
logging.debug("[rev] 初始化接口实现,使用账户cookies: {}".format(str(cookies)[:30]))
self.chatbot = Chatbot(cookies=cookies)
self.style = style
# 随机一个uuid作为实例名
import uuid
self.inst_name = str(uuid.uuid4())

def get_rev_lib_inst(self):
return self.chatbot

def get_reply(self, prompt: str, **kwargs) -> tuple[str, dict]:
"""获取回复"""
task = self.chatbot.ask(prompt, conversation_style=self.style)
resp = asyncio.run(task)
logging.debug(json.dumps(resp, indent=4, ensure_ascii=False))

reply_obj = resp["item"]["messages"][-1]
body = reply_obj["text"]

refs_str = "参考资料: \n"
index = 1
for ref in reply_obj["sourceAttributions"]:
refs_str += "[^"+str(index)+"^] "+ref["providerDisplayName"]+": "+ref["seeMoreUrl"] + "\n"
index += 1

throttling = resp["item"]["throttling"]

throttling_str = "本次对话: {}/{}".format(throttling["numUserMessagesInConversation"], throttling["maxNumUserMessagesInConversation"])

import revcfg
if hasattr(revcfg, "output_references") and not revcfg.output_references:
# 把正文的[^n^]替换成空
import re
body = re.sub(r"\[\^[0-9]+\^\]", "", body)

reply_str = body + "\n\n" + ((refs_str + "\n\n") if index != 1 and (not hasattr(revcfg, "output_references") or revcfg.output_references) else "") + throttling_str
yield reply_str, resp

def reset_chat(self):
asyncio.run(self.chatbot.reset())

def rollback(self):
pass
3 changes: 3 additions & 0 deletions pkg/process/impls/v1impl.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,16 @@

__thr_locks__ = {}


def get_lock(key: str):
if key not in __thr_locks__:
__thr_locks__[key] = threading.Lock()
return __thr_locks__[key]


import logging


class RevChatGPTV1(RevLibInterface):
"""acheong08/ChatGPT的逆向库接口 V1"""
chatbot: Chatbot = None
Expand Down
3 changes: 3 additions & 0 deletions pkg/process/procmsg.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ def process_message(session_name: str, prompt: str, host: PluginHost, **kwargs)
use_forward_msg_component = True
all_reply += section

if len(all_reply) > revcfg.blog_msg_threshold:
use_forward_msg_component = True

if use_forward_msg_component:
import config

Expand Down
8 changes: 7 additions & 1 deletion pkg/process/revss.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# 逆向库的session
from plugins.revLibs.pkg.models.interface import RevLibInterface
from plugins.revLibs.pkg.process.impls.v1impl import RevChatGPTV1
from plugins.revLibs.pkg.process.impls.edgegpt import EdgeGPTImpl
import pkg.openai.dprompt as dprompt

import logging
Expand Down Expand Up @@ -34,6 +35,10 @@ def __init__(self, name: str):
self.__rev_interface_impl__, valid, acc = __rev_interface_impl_class__.create_instance()
self.using_account = acc
self.reset()
elif __rev_interface_impl_class__ is EdgeGPTImpl:
logging.debug("[rev] 逆向接口实现为EdgeGPTImpl")
self.__rev_interface_impl__,_,_ = __rev_interface_impl_class__.create_instance()
self.reset()

def get_rev_lib_inst(self):
return self.__rev_interface_impl__.get_rev_lib_inst()
Expand Down Expand Up @@ -69,7 +74,8 @@ def get_reply(self, prompt: str, **kwargs) -> str:

# 改成迭代器以支持回复分节
for reply_period_msg, reply_period_dict in self.__rev_interface_impl__.get_reply(prompt, **kwargs):
self.conversation_id = reply_period_dict['conversation_id']
if __rev_interface_impl_class__ is RevChatGPTV1:
self.conversation_id = reply_period_dict['conversation_id']

yield reply_period_msg

Expand Down
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
revChatGPT~=4.0.0
revChatGPT~=4.0.0
EdgeGPT~=0.0.56.2
4 changes: 4 additions & 0 deletions revcfg-template.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# 选择使用的逆向库
# 目前支持以下库:
# - "acheong08/ChatGPT.V1": acheong08/ChatGPT库的V1版本
# - "acheong08/EdgeGPT": acheong08/EdgeGPT库,接入new bing
reverse_lib = "acheong08/ChatGPT.V1"

# [必填][❗此说明很重要,请您认真阅读❗] OpenAI账户信息
Expand Down Expand Up @@ -49,6 +50,9 @@
# 以分钟为单位
openai_account_resume_interval = 60

# 使用New Bing时是否显示参考资料
output_references = True

# 消息回复前缀
# 建议保留此前缀,以便区分GPT-3和此插件的回复
reply_prefix = "[REV]"
Expand Down

0 comments on commit f9834cb

Please sign in to comment.