镜像自地址
https://github.com/binary-husky/gpt_academic.git
已同步 2025-12-08 23:46:48 +00:00
format source code
这个提交包含在:
@@ -244,7 +244,7 @@ def predict(inputs, llm_kwargs, plugin_kwargs, chatbot, history=[], system_promp
|
||||
if has_choices and not choice_valid:
|
||||
# 一些垃圾第三方接口的出现这样的错误
|
||||
continue
|
||||
if len(chunk_decoded) > 0 and (chunkjson is None):
|
||||
if ('data: [DONE]' not in chunk_decoded) and len(chunk_decoded) > 0 and (chunkjson is None):
|
||||
# 传递进来一些奇怪的东西
|
||||
raise ValueError(f'无法读取以下数据,请检查配置。\n\n{chunk_decoded}')
|
||||
# 前者是API2D的结束条件,后者是OPENAI的结束条件
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
"""
|
||||
========================================================================
|
||||
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||||
第一部分:来自EdgeGPT.py
|
||||
https://github.com/acheong08/EdgeGPT
|
||||
========================================================================
|
||||
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||||
"""
|
||||
from .edge_gpt_free import Chatbot as NewbingChatbot
|
||||
|
||||
load_message = "等待NewBing响应。"
|
||||
|
||||
"""
|
||||
========================================================================
|
||||
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||||
第二部分:子进程Worker(调用主体)
|
||||
========================================================================
|
||||
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||||
"""
|
||||
import time
|
||||
import json
|
||||
@@ -22,19 +23,30 @@ import threading
|
||||
from toolbox import update_ui, get_conf, trimmed_format_exc
|
||||
from multiprocessing import Process, Pipe
|
||||
|
||||
|
||||
def preprocess_newbing_out(s):
|
||||
pattern = r'\^(\d+)\^' # 匹配^数字^
|
||||
sub = lambda m: '('+m.group(1)+')' # 将匹配到的数字作为替换值
|
||||
result = re.sub(pattern, sub, s) # 替换操作
|
||||
if '[1]' in result:
|
||||
result += '\n\n```reference\n' + "\n".join([r for r in result.split('\n') if r.startswith('[')]) + '\n```\n'
|
||||
pattern = r"\^(\d+)\^" # 匹配^数字^
|
||||
sub = lambda m: "(" + m.group(1) + ")" # 将匹配到的数字作为替换值
|
||||
result = re.sub(pattern, sub, s) # 替换操作
|
||||
if "[1]" in result:
|
||||
result += (
|
||||
"\n\n```reference\n"
|
||||
+ "\n".join([r for r in result.split("\n") if r.startswith("[")])
|
||||
+ "\n```\n"
|
||||
)
|
||||
return result
|
||||
|
||||
|
||||
def preprocess_newbing_out_simple(result):
|
||||
if '[1]' in result:
|
||||
result += '\n\n```reference\n' + "\n".join([r for r in result.split('\n') if r.startswith('[')]) + '\n```\n'
|
||||
if "[1]" in result:
|
||||
result += (
|
||||
"\n\n```reference\n"
|
||||
+ "\n".join([r for r in result.split("\n") if r.startswith("[")])
|
||||
+ "\n```\n"
|
||||
)
|
||||
return result
|
||||
|
||||
|
||||
class NewBingHandle(Process):
|
||||
def __init__(self):
|
||||
super().__init__(daemon=True)
|
||||
@@ -46,11 +58,12 @@ class NewBingHandle(Process):
|
||||
self.check_dependency()
|
||||
self.start()
|
||||
self.threadLock = threading.Lock()
|
||||
|
||||
|
||||
def check_dependency(self):
|
||||
try:
|
||||
self.success = False
|
||||
import certifi, httpx, rich
|
||||
|
||||
self.info = "依赖检测通过,等待NewBing响应。注意目前不能多人同时调用NewBing接口(有线程锁),否则将导致每个人的NewBing问询历史互相渗透。调用NewBing时,会自动使用已配置的代理。"
|
||||
self.success = True
|
||||
except:
|
||||
@@ -62,18 +75,19 @@ class NewBingHandle(Process):
|
||||
|
||||
async def async_run(self):
|
||||
# 读取配置
|
||||
NEWBING_STYLE = get_conf('NEWBING_STYLE')
|
||||
NEWBING_STYLE = get_conf("NEWBING_STYLE")
|
||||
from request_llms.bridge_all import model_info
|
||||
endpoint = model_info['newbing']['endpoint']
|
||||
|
||||
endpoint = model_info["newbing"]["endpoint"]
|
||||
while True:
|
||||
# 等待
|
||||
kwargs = self.child.recv()
|
||||
question=kwargs['query']
|
||||
history=kwargs['history']
|
||||
system_prompt=kwargs['system_prompt']
|
||||
question = kwargs["query"]
|
||||
history = kwargs["history"]
|
||||
system_prompt = kwargs["system_prompt"]
|
||||
|
||||
# 是否重置
|
||||
if len(self.local_history) > 0 and len(history)==0:
|
||||
if len(self.local_history) > 0 and len(history) == 0:
|
||||
await self.newbing_model.reset()
|
||||
self.local_history = []
|
||||
|
||||
@@ -81,34 +95,33 @@ class NewBingHandle(Process):
|
||||
prompt = ""
|
||||
if system_prompt not in self.local_history:
|
||||
self.local_history.append(system_prompt)
|
||||
prompt += system_prompt + '\n'
|
||||
prompt += system_prompt + "\n"
|
||||
|
||||
# 追加历史
|
||||
for ab in history:
|
||||
a, b = ab
|
||||
if a not in self.local_history:
|
||||
self.local_history.append(a)
|
||||
prompt += a + '\n'
|
||||
prompt += a + "\n"
|
||||
|
||||
# 问题
|
||||
prompt += question
|
||||
self.local_history.append(question)
|
||||
print('question:', prompt)
|
||||
print("question:", prompt)
|
||||
# 提交
|
||||
async for final, response in self.newbing_model.ask_stream(
|
||||
prompt=question,
|
||||
conversation_style=NEWBING_STYLE, # ["creative", "balanced", "precise"]
|
||||
wss_link=endpoint, # "wss://sydney.bing.com/sydney/ChatHub"
|
||||
conversation_style=NEWBING_STYLE, # ["creative", "balanced", "precise"]
|
||||
wss_link=endpoint, # "wss://sydney.bing.com/sydney/ChatHub"
|
||||
):
|
||||
if not final:
|
||||
print(response)
|
||||
self.child.send(str(response))
|
||||
else:
|
||||
print('-------- receive final ---------')
|
||||
self.child.send('[Finish]')
|
||||
print("-------- receive final ---------")
|
||||
self.child.send("[Finish]")
|
||||
# self.local_history.append(response)
|
||||
|
||||
|
||||
def run(self):
|
||||
"""
|
||||
这个函数运行在子进程
|
||||
@@ -118,32 +131,37 @@ class NewBingHandle(Process):
|
||||
self.local_history = []
|
||||
if (self.newbing_model is None) or (not self.success):
|
||||
# 代理设置
|
||||
proxies, NEWBING_COOKIES = get_conf('proxies', 'NEWBING_COOKIES')
|
||||
if proxies is None:
|
||||
proxies, NEWBING_COOKIES = get_conf("proxies", "NEWBING_COOKIES")
|
||||
if proxies is None:
|
||||
self.proxies_https = None
|
||||
else:
|
||||
self.proxies_https = proxies['https']
|
||||
else:
|
||||
self.proxies_https = proxies["https"]
|
||||
|
||||
if (NEWBING_COOKIES is not None) and len(NEWBING_COOKIES) > 100:
|
||||
try:
|
||||
cookies = json.loads(NEWBING_COOKIES)
|
||||
except:
|
||||
self.success = False
|
||||
tb_str = '\n```\n' + trimmed_format_exc() + '\n```\n'
|
||||
self.child.send(f'[Local Message] NEWBING_COOKIES未填写或有格式错误。')
|
||||
self.child.send('[Fail]'); self.child.send('[Finish]')
|
||||
tb_str = "\n```\n" + trimmed_format_exc() + "\n```\n"
|
||||
self.child.send(f"[Local Message] NEWBING_COOKIES未填写或有格式错误。")
|
||||
self.child.send("[Fail]")
|
||||
self.child.send("[Finish]")
|
||||
raise RuntimeError(f"NEWBING_COOKIES未填写或有格式错误。")
|
||||
else:
|
||||
cookies = None
|
||||
|
||||
try:
|
||||
self.newbing_model = NewbingChatbot(proxy=self.proxies_https, cookies=cookies)
|
||||
self.newbing_model = NewbingChatbot(
|
||||
proxy=self.proxies_https, cookies=cookies
|
||||
)
|
||||
except:
|
||||
self.success = False
|
||||
tb_str = '\n```\n' + trimmed_format_exc() + '\n```\n'
|
||||
self.child.send(f'[Local Message] 不能加载Newbing组件,请注意Newbing组件已不再维护。{tb_str}')
|
||||
self.child.send('[Fail]')
|
||||
self.child.send('[Finish]')
|
||||
tb_str = "\n```\n" + trimmed_format_exc() + "\n```\n"
|
||||
self.child.send(
|
||||
f"[Local Message] 不能加载Newbing组件,请注意Newbing组件已不再维护。{tb_str}"
|
||||
)
|
||||
self.child.send("[Fail]")
|
||||
self.child.send("[Finish]")
|
||||
raise RuntimeError(f"不能加载Newbing组件,请注意Newbing组件已不再维护。")
|
||||
|
||||
self.success = True
|
||||
@@ -151,66 +169,100 @@ class NewBingHandle(Process):
|
||||
# 进入任务等待状态
|
||||
asyncio.run(self.async_run())
|
||||
except Exception:
|
||||
tb_str = '\n```\n' + trimmed_format_exc() + '\n```\n'
|
||||
self.child.send(f'[Local Message] Newbing 请求失败,报错信息如下. 如果是与网络相关的问题,建议更换代理协议(推荐http)或代理节点 {tb_str}.')
|
||||
self.child.send('[Fail]')
|
||||
self.child.send('[Finish]')
|
||||
|
||||
tb_str = "\n```\n" + trimmed_format_exc() + "\n```\n"
|
||||
self.child.send(
|
||||
f"[Local Message] Newbing 请求失败,报错信息如下. 如果是与网络相关的问题,建议更换代理协议(推荐http)或代理节点 {tb_str}."
|
||||
)
|
||||
self.child.send("[Fail]")
|
||||
self.child.send("[Finish]")
|
||||
|
||||
def stream_chat(self, **kwargs):
|
||||
"""
|
||||
这个函数运行在主进程
|
||||
"""
|
||||
self.threadLock.acquire() # 获取线程锁
|
||||
self.parent.send(kwargs) # 请求子进程
|
||||
self.threadLock.acquire() # 获取线程锁
|
||||
self.parent.send(kwargs) # 请求子进程
|
||||
while True:
|
||||
res = self.parent.recv() # 等待newbing回复的片段
|
||||
if res == '[Finish]': break # 结束
|
||||
elif res == '[Fail]': self.success = False; break # 失败
|
||||
else: yield res # newbing回复的片段
|
||||
self.threadLock.release() # 释放线程锁
|
||||
res = self.parent.recv() # 等待newbing回复的片段
|
||||
if res == "[Finish]":
|
||||
break # 结束
|
||||
elif res == "[Fail]":
|
||||
self.success = False
|
||||
break # 失败
|
||||
else:
|
||||
yield res # newbing回复的片段
|
||||
self.threadLock.release() # 释放线程锁
|
||||
|
||||
|
||||
"""
|
||||
========================================================================
|
||||
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||||
第三部分:主进程统一调用函数接口
|
||||
========================================================================
|
||||
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||||
"""
|
||||
global newbingfree_handle
|
||||
newbingfree_handle = None
|
||||
|
||||
def predict_no_ui_long_connection(inputs, llm_kwargs, history=[], sys_prompt="", observe_window=[], console_slience=False):
|
||||
|
||||
def predict_no_ui_long_connection(
|
||||
inputs,
|
||||
llm_kwargs,
|
||||
history=[],
|
||||
sys_prompt="",
|
||||
observe_window=[],
|
||||
console_slience=False,
|
||||
):
|
||||
"""
|
||||
多线程方法
|
||||
函数的说明请见 request_llms/bridge_all.py
|
||||
多线程方法
|
||||
函数的说明请见 request_llms/bridge_all.py
|
||||
"""
|
||||
global newbingfree_handle
|
||||
if (newbingfree_handle is None) or (not newbingfree_handle.success):
|
||||
newbingfree_handle = NewBingHandle()
|
||||
if len(observe_window) >= 1: observe_window[0] = load_message + "\n\n" + newbingfree_handle.info
|
||||
if not newbingfree_handle.success:
|
||||
if len(observe_window) >= 1:
|
||||
observe_window[0] = load_message + "\n\n" + newbingfree_handle.info
|
||||
if not newbingfree_handle.success:
|
||||
error = newbingfree_handle.info
|
||||
newbingfree_handle = None
|
||||
raise RuntimeError(error)
|
||||
|
||||
# 没有 sys_prompt 接口,因此把prompt加入 history
|
||||
history_feedin = []
|
||||
for i in range(len(history)//2):
|
||||
history_feedin.append([history[2*i], history[2*i+1]] )
|
||||
for i in range(len(history) // 2):
|
||||
history_feedin.append([history[2 * i], history[2 * i + 1]])
|
||||
|
||||
watch_dog_patience = 5 # 看门狗 (watchdog) 的耐心, 设置5秒即可
|
||||
watch_dog_patience = 5 # 看门狗 (watchdog) 的耐心, 设置5秒即可
|
||||
response = ""
|
||||
if len(observe_window) >= 1: observe_window[0] = "[Local Message] 等待NewBing响应中 ..."
|
||||
for response in newbingfree_handle.stream_chat(query=inputs, history=history_feedin, system_prompt=sys_prompt, max_length=llm_kwargs['max_length'], top_p=llm_kwargs['top_p'], temperature=llm_kwargs['temperature']):
|
||||
if len(observe_window) >= 1: observe_window[0] = preprocess_newbing_out_simple(response)
|
||||
if len(observe_window) >= 2:
|
||||
if (time.time()-observe_window[1]) > watch_dog_patience:
|
||||
if len(observe_window) >= 1:
|
||||
observe_window[0] = "[Local Message] 等待NewBing响应中 ..."
|
||||
for response in newbingfree_handle.stream_chat(
|
||||
query=inputs,
|
||||
history=history_feedin,
|
||||
system_prompt=sys_prompt,
|
||||
max_length=llm_kwargs["max_length"],
|
||||
top_p=llm_kwargs["top_p"],
|
||||
temperature=llm_kwargs["temperature"],
|
||||
):
|
||||
if len(observe_window) >= 1:
|
||||
observe_window[0] = preprocess_newbing_out_simple(response)
|
||||
if len(observe_window) >= 2:
|
||||
if (time.time() - observe_window[1]) > watch_dog_patience:
|
||||
raise RuntimeError("程序终止。")
|
||||
return preprocess_newbing_out_simple(response)
|
||||
|
||||
def predict(inputs, llm_kwargs, plugin_kwargs, chatbot, history=[], system_prompt='', stream = True, additional_fn=None):
|
||||
|
||||
def predict(
|
||||
inputs,
|
||||
llm_kwargs,
|
||||
plugin_kwargs,
|
||||
chatbot,
|
||||
history=[],
|
||||
system_prompt="",
|
||||
stream=True,
|
||||
additional_fn=None,
|
||||
):
|
||||
"""
|
||||
单线程方法
|
||||
函数的说明请见 request_llms/bridge_all.py
|
||||
单线程方法
|
||||
函数的说明请见 request_llms/bridge_all.py
|
||||
"""
|
||||
chatbot.append((inputs, "[Local Message] 等待NewBing响应中 ..."))
|
||||
|
||||
@@ -219,27 +271,41 @@ def predict(inputs, llm_kwargs, plugin_kwargs, chatbot, history=[], system_promp
|
||||
newbingfree_handle = NewBingHandle()
|
||||
chatbot[-1] = (inputs, load_message + "\n\n" + newbingfree_handle.info)
|
||||
yield from update_ui(chatbot=chatbot, history=[])
|
||||
if not newbingfree_handle.success:
|
||||
if not newbingfree_handle.success:
|
||||
newbingfree_handle = None
|
||||
return
|
||||
|
||||
if additional_fn is not None:
|
||||
from core_functional import handle_core_functionality
|
||||
inputs, history = handle_core_functionality(additional_fn, inputs, history, chatbot)
|
||||
|
||||
inputs, history = handle_core_functionality(
|
||||
additional_fn, inputs, history, chatbot
|
||||
)
|
||||
|
||||
history_feedin = []
|
||||
for i in range(len(history)//2):
|
||||
history_feedin.append([history[2*i], history[2*i+1]] )
|
||||
for i in range(len(history) // 2):
|
||||
history_feedin.append([history[2 * i], history[2 * i + 1]])
|
||||
|
||||
chatbot[-1] = (inputs, "[Local Message] 等待NewBing响应中 ...")
|
||||
response = "[Local Message] 等待NewBing响应中 ..."
|
||||
yield from update_ui(chatbot=chatbot, history=history, msg="NewBing响应缓慢,尚未完成全部响应,请耐心完成后再提交新问题。")
|
||||
for response in newbingfree_handle.stream_chat(query=inputs, history=history_feedin, system_prompt=system_prompt, max_length=llm_kwargs['max_length'], top_p=llm_kwargs['top_p'], temperature=llm_kwargs['temperature']):
|
||||
yield from update_ui(
|
||||
chatbot=chatbot, history=history, msg="NewBing响应缓慢,尚未完成全部响应,请耐心完成后再提交新问题。"
|
||||
)
|
||||
for response in newbingfree_handle.stream_chat(
|
||||
query=inputs,
|
||||
history=history_feedin,
|
||||
system_prompt=system_prompt,
|
||||
max_length=llm_kwargs["max_length"],
|
||||
top_p=llm_kwargs["top_p"],
|
||||
temperature=llm_kwargs["temperature"],
|
||||
):
|
||||
chatbot[-1] = (inputs, preprocess_newbing_out(response))
|
||||
yield from update_ui(chatbot=chatbot, history=history, msg="NewBing响应缓慢,尚未完成全部响应,请耐心完成后再提交新问题。")
|
||||
if response == "[Local Message] 等待NewBing响应中 ...": response = "[Local Message] NewBing响应异常,请刷新界面重试 ..."
|
||||
yield from update_ui(
|
||||
chatbot=chatbot, history=history, msg="NewBing响应缓慢,尚未完成全部响应,请耐心完成后再提交新问题。"
|
||||
)
|
||||
if response == "[Local Message] 等待NewBing响应中 ...":
|
||||
response = "[Local Message] NewBing响应异常,请刷新界面重试 ..."
|
||||
history.extend([inputs, response])
|
||||
logging.info(f'[raw_input] {inputs}')
|
||||
logging.info(f'[response] {response}')
|
||||
logging.info(f"[raw_input] {inputs}")
|
||||
logging.info(f"[response] {response}")
|
||||
yield from update_ui(chatbot=chatbot, history=history, msg="完成全部响应,请提交新问题。")
|
||||
|
||||
|
||||
@@ -7,14 +7,15 @@ import logging
|
||||
import time
|
||||
from toolbox import get_conf
|
||||
import asyncio
|
||||
|
||||
load_message = "正在加载Claude组件,请稍候..."
|
||||
|
||||
try:
|
||||
"""
|
||||
========================================================================
|
||||
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||||
第一部分:Slack API Client
|
||||
https://github.com/yokonsan/claude-in-slack-api
|
||||
========================================================================
|
||||
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||||
"""
|
||||
|
||||
from slack_sdk.errors import SlackApiError
|
||||
@@ -23,20 +24,23 @@ try:
|
||||
class SlackClient(AsyncWebClient):
|
||||
"""SlackClient类用于与Slack API进行交互,实现消息发送、接收等功能。
|
||||
|
||||
属性:
|
||||
- CHANNEL_ID:str类型,表示频道ID。
|
||||
属性:
|
||||
- CHANNEL_ID:str类型,表示频道ID。
|
||||
|
||||
方法:
|
||||
- open_channel():异步方法。通过调用conversations_open方法打开一个频道,并将返回的频道ID保存在属性CHANNEL_ID中。
|
||||
- chat(text: str):异步方法。向已打开的频道发送一条文本消息。
|
||||
- get_slack_messages():异步方法。获取已打开频道的最新消息并返回消息列表,目前不支持历史消息查询。
|
||||
- get_reply():异步方法。循环监听已打开频道的消息,如果收到"Typing…_"结尾的消息说明Claude还在继续输出,否则结束循环。
|
||||
方法:
|
||||
- open_channel():异步方法。通过调用conversations_open方法打开一个频道,并将返回的频道ID保存在属性CHANNEL_ID中。
|
||||
- chat(text: str):异步方法。向已打开的频道发送一条文本消息。
|
||||
- get_slack_messages():异步方法。获取已打开频道的最新消息并返回消息列表,目前不支持历史消息查询。
|
||||
- get_reply():异步方法。循环监听已打开频道的消息,如果收到"Typing…_"结尾的消息说明Claude还在继续输出,否则结束循环。
|
||||
|
||||
"""
|
||||
|
||||
CHANNEL_ID = None
|
||||
|
||||
async def open_channel(self):
|
||||
response = await self.conversations_open(users=get_conf('SLACK_CLAUDE_BOT_ID'))
|
||||
response = await self.conversations_open(
|
||||
users=get_conf("SLACK_CLAUDE_BOT_ID")
|
||||
)
|
||||
self.CHANNEL_ID = response["channel"]["id"]
|
||||
|
||||
async def chat(self, text):
|
||||
@@ -49,33 +53,39 @@ try:
|
||||
async def get_slack_messages(self):
|
||||
try:
|
||||
# TODO:暂时不支持历史消息,因为在同一个频道里存在多人使用时历史消息渗透问题
|
||||
resp = await self.conversations_history(channel=self.CHANNEL_ID, oldest=self.LAST_TS, limit=1)
|
||||
msg = [msg for msg in resp["messages"]
|
||||
if msg.get("user") == get_conf('SLACK_CLAUDE_BOT_ID')]
|
||||
resp = await self.conversations_history(
|
||||
channel=self.CHANNEL_ID, oldest=self.LAST_TS, limit=1
|
||||
)
|
||||
msg = [
|
||||
msg
|
||||
for msg in resp["messages"]
|
||||
if msg.get("user") == get_conf("SLACK_CLAUDE_BOT_ID")
|
||||
]
|
||||
return msg
|
||||
except (SlackApiError, KeyError) as e:
|
||||
raise RuntimeError(f"获取Slack消息失败。")
|
||||
|
||||
|
||||
async def get_reply(self):
|
||||
while True:
|
||||
slack_msgs = await self.get_slack_messages()
|
||||
if len(slack_msgs) == 0:
|
||||
await asyncio.sleep(0.5)
|
||||
continue
|
||||
|
||||
|
||||
msg = slack_msgs[-1]
|
||||
if msg["text"].endswith("Typing…_"):
|
||||
yield False, msg["text"]
|
||||
else:
|
||||
yield True, msg["text"]
|
||||
break
|
||||
|
||||
except:
|
||||
pass
|
||||
|
||||
"""
|
||||
========================================================================
|
||||
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||||
第二部分:子进程Worker(调用主体)
|
||||
========================================================================
|
||||
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||||
"""
|
||||
|
||||
|
||||
@@ -88,7 +98,7 @@ class ClaudeHandle(Process):
|
||||
self.success = True
|
||||
self.local_history = []
|
||||
self.check_dependency()
|
||||
if self.success:
|
||||
if self.success:
|
||||
self.start()
|
||||
self.threadLock = threading.Lock()
|
||||
|
||||
@@ -96,6 +106,7 @@ class ClaudeHandle(Process):
|
||||
try:
|
||||
self.success = False
|
||||
import slack_sdk
|
||||
|
||||
self.info = "依赖检测通过,等待Claude响应。注意目前不能多人同时调用Claude接口(有线程锁),否则将导致每个人的Claude问询历史互相渗透。调用Claude时,会自动使用已配置的代理。"
|
||||
self.success = True
|
||||
except:
|
||||
@@ -103,40 +114,44 @@ class ClaudeHandle(Process):
|
||||
self.success = False
|
||||
|
||||
def ready(self):
|
||||
return self.claude_model is not None
|
||||
|
||||
return self.claude_model is not None
|
||||
|
||||
async def async_run(self):
|
||||
await self.claude_model.open_channel()
|
||||
while True:
|
||||
# 等待
|
||||
kwargs = self.child.recv()
|
||||
question = kwargs['query']
|
||||
history = kwargs['history']
|
||||
question = kwargs["query"]
|
||||
history = kwargs["history"]
|
||||
|
||||
# 开始问问题
|
||||
prompt = ""
|
||||
|
||||
# 问题
|
||||
prompt += question
|
||||
print('question:', prompt)
|
||||
print("question:", prompt)
|
||||
|
||||
# 提交
|
||||
await self.claude_model.chat(prompt)
|
||||
|
||||
|
||||
# 获取回复
|
||||
async for final, response in self.claude_model.get_reply():
|
||||
async for final, response in self.claude_model.get_reply():
|
||||
if not final:
|
||||
print(response)
|
||||
self.child.send(str(response))
|
||||
else:
|
||||
# 防止丢失最后一条消息
|
||||
slack_msgs = await self.claude_model.get_slack_messages()
|
||||
last_msg = slack_msgs[-1]["text"] if slack_msgs and len(slack_msgs) > 0 else ""
|
||||
last_msg = (
|
||||
slack_msgs[-1]["text"]
|
||||
if slack_msgs and len(slack_msgs) > 0
|
||||
else ""
|
||||
)
|
||||
if last_msg:
|
||||
self.child.send(last_msg)
|
||||
print('-------- receive final ---------')
|
||||
self.child.send('[Finish]')
|
||||
|
||||
print("-------- receive final ---------")
|
||||
self.child.send("[Finish]")
|
||||
|
||||
def run(self):
|
||||
"""
|
||||
这个函数运行在子进程
|
||||
@@ -146,22 +161,24 @@ class ClaudeHandle(Process):
|
||||
self.local_history = []
|
||||
if (self.claude_model is None) or (not self.success):
|
||||
# 代理设置
|
||||
proxies = get_conf('proxies')
|
||||
proxies = get_conf("proxies")
|
||||
if proxies is None:
|
||||
self.proxies_https = None
|
||||
else:
|
||||
self.proxies_https = proxies['https']
|
||||
self.proxies_https = proxies["https"]
|
||||
|
||||
try:
|
||||
SLACK_CLAUDE_USER_TOKEN = get_conf('SLACK_CLAUDE_USER_TOKEN')
|
||||
self.claude_model = SlackClient(token=SLACK_CLAUDE_USER_TOKEN, proxy=self.proxies_https)
|
||||
print('Claude组件初始化成功。')
|
||||
SLACK_CLAUDE_USER_TOKEN = get_conf("SLACK_CLAUDE_USER_TOKEN")
|
||||
self.claude_model = SlackClient(
|
||||
token=SLACK_CLAUDE_USER_TOKEN, proxy=self.proxies_https
|
||||
)
|
||||
print("Claude组件初始化成功。")
|
||||
except:
|
||||
self.success = False
|
||||
tb_str = '\n```\n' + trimmed_format_exc() + '\n```\n'
|
||||
self.child.send(f'[Local Message] 不能加载Claude组件。{tb_str}')
|
||||
self.child.send('[Fail]')
|
||||
self.child.send('[Finish]')
|
||||
tb_str = "\n```\n" + trimmed_format_exc() + "\n```\n"
|
||||
self.child.send(f"[Local Message] 不能加载Claude组件。{tb_str}")
|
||||
self.child.send("[Fail]")
|
||||
self.child.send("[Finish]")
|
||||
raise RuntimeError(f"不能加载Claude组件。")
|
||||
|
||||
self.success = True
|
||||
@@ -169,42 +186,49 @@ class ClaudeHandle(Process):
|
||||
# 进入任务等待状态
|
||||
asyncio.run(self.async_run())
|
||||
except Exception:
|
||||
tb_str = '\n```\n' + trimmed_format_exc() + '\n```\n'
|
||||
self.child.send(f'[Local Message] Claude失败 {tb_str}.')
|
||||
self.child.send('[Fail]')
|
||||
self.child.send('[Finish]')
|
||||
tb_str = "\n```\n" + trimmed_format_exc() + "\n```\n"
|
||||
self.child.send(f"[Local Message] Claude失败 {tb_str}.")
|
||||
self.child.send("[Fail]")
|
||||
self.child.send("[Finish]")
|
||||
|
||||
def stream_chat(self, **kwargs):
|
||||
"""
|
||||
这个函数运行在主进程
|
||||
"""
|
||||
self.threadLock.acquire()
|
||||
self.parent.send(kwargs) # 发送请求到子进程
|
||||
self.parent.send(kwargs) # 发送请求到子进程
|
||||
while True:
|
||||
res = self.parent.recv() # 等待Claude回复的片段
|
||||
if res == '[Finish]':
|
||||
break # 结束
|
||||
elif res == '[Fail]':
|
||||
res = self.parent.recv() # 等待Claude回复的片段
|
||||
if res == "[Finish]":
|
||||
break # 结束
|
||||
elif res == "[Fail]":
|
||||
self.success = False
|
||||
break
|
||||
else:
|
||||
yield res # Claude回复的片段
|
||||
yield res # Claude回复的片段
|
||||
self.threadLock.release()
|
||||
|
||||
|
||||
"""
|
||||
========================================================================
|
||||
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||||
第三部分:主进程统一调用函数接口
|
||||
========================================================================
|
||||
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||||
"""
|
||||
global claude_handle
|
||||
claude_handle = None
|
||||
|
||||
|
||||
def predict_no_ui_long_connection(inputs, llm_kwargs, history=[], sys_prompt="", observe_window=None, console_slience=False):
|
||||
def predict_no_ui_long_connection(
|
||||
inputs,
|
||||
llm_kwargs,
|
||||
history=[],
|
||||
sys_prompt="",
|
||||
observe_window=None,
|
||||
console_slience=False,
|
||||
):
|
||||
"""
|
||||
多线程方法
|
||||
函数的说明请见 request_llms/bridge_all.py
|
||||
多线程方法
|
||||
函数的说明请见 request_llms/bridge_all.py
|
||||
"""
|
||||
global claude_handle
|
||||
if (claude_handle is None) or (not claude_handle.success):
|
||||
@@ -217,24 +241,40 @@ def predict_no_ui_long_connection(inputs, llm_kwargs, history=[], sys_prompt="",
|
||||
|
||||
# 没有 sys_prompt 接口,因此把prompt加入 history
|
||||
history_feedin = []
|
||||
for i in range(len(history)//2):
|
||||
history_feedin.append([history[2*i], history[2*i+1]])
|
||||
for i in range(len(history) // 2):
|
||||
history_feedin.append([history[2 * i], history[2 * i + 1]])
|
||||
|
||||
watch_dog_patience = 5 # 看门狗 (watchdog) 的耐心, 设置5秒即可
|
||||
response = ""
|
||||
observe_window[0] = "[Local Message] 等待Claude响应中 ..."
|
||||
for response in claude_handle.stream_chat(query=inputs, history=history_feedin, system_prompt=sys_prompt, max_length=llm_kwargs['max_length'], top_p=llm_kwargs['top_p'], temperature=llm_kwargs['temperature']):
|
||||
for response in claude_handle.stream_chat(
|
||||
query=inputs,
|
||||
history=history_feedin,
|
||||
system_prompt=sys_prompt,
|
||||
max_length=llm_kwargs["max_length"],
|
||||
top_p=llm_kwargs["top_p"],
|
||||
temperature=llm_kwargs["temperature"],
|
||||
):
|
||||
observe_window[0] = preprocess_newbing_out_simple(response)
|
||||
if len(observe_window) >= 2:
|
||||
if (time.time()-observe_window[1]) > watch_dog_patience:
|
||||
if (time.time() - observe_window[1]) > watch_dog_patience:
|
||||
raise RuntimeError("程序终止。")
|
||||
return preprocess_newbing_out_simple(response)
|
||||
|
||||
|
||||
def predict(inputs, llm_kwargs, plugin_kwargs, chatbot, history=[], system_prompt='', stream=True, additional_fn=None):
|
||||
def predict(
|
||||
inputs,
|
||||
llm_kwargs,
|
||||
plugin_kwargs,
|
||||
chatbot,
|
||||
history=[],
|
||||
system_prompt="",
|
||||
stream=True,
|
||||
additional_fn=None,
|
||||
):
|
||||
"""
|
||||
单线程方法
|
||||
函数的说明请见 request_llms/bridge_all.py
|
||||
单线程方法
|
||||
函数的说明请见 request_llms/bridge_all.py
|
||||
"""
|
||||
chatbot.append((inputs, "[Local Message] 等待Claude响应中 ..."))
|
||||
|
||||
@@ -249,21 +289,30 @@ def predict(inputs, llm_kwargs, plugin_kwargs, chatbot, history=[], system_promp
|
||||
|
||||
if additional_fn is not None:
|
||||
from core_functional import handle_core_functionality
|
||||
inputs, history = handle_core_functionality(additional_fn, inputs, history, chatbot)
|
||||
|
||||
inputs, history = handle_core_functionality(
|
||||
additional_fn, inputs, history, chatbot
|
||||
)
|
||||
|
||||
history_feedin = []
|
||||
for i in range(len(history)//2):
|
||||
history_feedin.append([history[2*i], history[2*i+1]])
|
||||
for i in range(len(history) // 2):
|
||||
history_feedin.append([history[2 * i], history[2 * i + 1]])
|
||||
|
||||
chatbot[-1] = (inputs, "[Local Message] 等待Claude响应中 ...")
|
||||
response = "[Local Message] 等待Claude响应中 ..."
|
||||
yield from update_ui(chatbot=chatbot, history=history, msg="Claude响应缓慢,尚未完成全部响应,请耐心完成后再提交新问题。")
|
||||
for response in claude_handle.stream_chat(query=inputs, history=history_feedin, system_prompt=system_prompt):
|
||||
yield from update_ui(
|
||||
chatbot=chatbot, history=history, msg="Claude响应缓慢,尚未完成全部响应,请耐心完成后再提交新问题。"
|
||||
)
|
||||
for response in claude_handle.stream_chat(
|
||||
query=inputs, history=history_feedin, system_prompt=system_prompt
|
||||
):
|
||||
chatbot[-1] = (inputs, preprocess_newbing_out(response))
|
||||
yield from update_ui(chatbot=chatbot, history=history, msg="Claude响应缓慢,尚未完成全部响应,请耐心完成后再提交新问题。")
|
||||
yield from update_ui(
|
||||
chatbot=chatbot, history=history, msg="Claude响应缓慢,尚未完成全部响应,请耐心完成后再提交新问题。"
|
||||
)
|
||||
if response == "[Local Message] 等待Claude响应中 ...":
|
||||
response = "[Local Message] Claude响应异常,请刷新界面重试 ..."
|
||||
history.extend([inputs, response])
|
||||
logging.info(f'[raw_input] {inputs}')
|
||||
logging.info(f'[response] {response}')
|
||||
logging.info(f"[raw_input] {inputs}")
|
||||
logging.info(f"[response] {response}")
|
||||
yield from update_ui(chatbot=chatbot, history=history, msg="完成全部响应,请提交新问题。")
|
||||
|
||||
@@ -12,7 +12,7 @@ from toolbox import get_conf, encode_image, get_pictures_list
|
||||
proxies, TIMEOUT_SECONDS = get_conf("proxies", "TIMEOUT_SECONDS")
|
||||
|
||||
"""
|
||||
========================================================================
|
||||
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||||
第五部分 一些文件处理方法
|
||||
files_filter_handler 根据type过滤文件
|
||||
input_encode_handler 提取input中的文件,并解析
|
||||
@@ -21,6 +21,7 @@ link_mtime_to_md 文件增加本地时间参数,避免下载到缓存文件
|
||||
html_view_blank 超链接
|
||||
html_local_file 本地文件取相对路径
|
||||
to_markdown_tabs 文件list 转换为 md tab
|
||||
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||||
"""
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
"""
|
||||
========================================================================
|
||||
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||||
第一部分:来自EdgeGPT.py
|
||||
https://github.com/acheong08/EdgeGPT
|
||||
========================================================================
|
||||
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||||
"""
|
||||
"""
|
||||
Main.py
|
||||
@@ -196,9 +196,9 @@ class _ChatHubRequest:
|
||||
self,
|
||||
prompt: str,
|
||||
conversation_style: CONVERSATION_STYLE_TYPE,
|
||||
options = None,
|
||||
webpage_context = None,
|
||||
search_result = False,
|
||||
options=None,
|
||||
webpage_context=None,
|
||||
search_result=False,
|
||||
) -> None:
|
||||
"""
|
||||
Updates request object
|
||||
@@ -294,9 +294,9 @@ class _Conversation:
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
proxy = None,
|
||||
async_mode = False,
|
||||
cookies = None,
|
||||
proxy=None,
|
||||
async_mode=False,
|
||||
cookies=None,
|
||||
) -> None:
|
||||
if async_mode:
|
||||
return
|
||||
@@ -350,8 +350,8 @@ class _Conversation:
|
||||
|
||||
@staticmethod
|
||||
async def create(
|
||||
proxy = None,
|
||||
cookies = None,
|
||||
proxy=None,
|
||||
cookies=None,
|
||||
):
|
||||
self = _Conversation(async_mode=True)
|
||||
self.struct = {
|
||||
@@ -418,8 +418,8 @@ class _ChatHub:
|
||||
def __init__(
|
||||
self,
|
||||
conversation: _Conversation,
|
||||
proxy = None,
|
||||
cookies = None,
|
||||
proxy=None,
|
||||
cookies=None,
|
||||
) -> None:
|
||||
self.session = None
|
||||
self.wss = None
|
||||
@@ -441,7 +441,7 @@ class _ChatHub:
|
||||
conversation_style: CONVERSATION_STYLE_TYPE = None,
|
||||
raw: bool = False,
|
||||
options: dict = None,
|
||||
webpage_context = None,
|
||||
webpage_context=None,
|
||||
search_result: bool = False,
|
||||
) -> Generator[str, None, None]:
|
||||
"""
|
||||
@@ -452,10 +452,12 @@ class _ChatHub:
|
||||
ws_cookies = []
|
||||
for cookie in self.cookies:
|
||||
ws_cookies.append(f"{cookie['name']}={cookie['value']}")
|
||||
req_header.update({
|
||||
'Cookie': ';'.join(ws_cookies),
|
||||
})
|
||||
|
||||
req_header.update(
|
||||
{
|
||||
"Cookie": ";".join(ws_cookies),
|
||||
}
|
||||
)
|
||||
|
||||
timeout = aiohttp.ClientTimeout(total=30)
|
||||
self.session = aiohttp.ClientSession(timeout=timeout)
|
||||
|
||||
@@ -521,9 +523,9 @@ class _ChatHub:
|
||||
msg = await self.wss.receive()
|
||||
try:
|
||||
objects = msg.data.split(DELIMITER)
|
||||
except :
|
||||
except:
|
||||
continue
|
||||
|
||||
|
||||
for obj in objects:
|
||||
if obj is None or not obj:
|
||||
continue
|
||||
@@ -624,8 +626,8 @@ class Chatbot:
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
proxy = None,
|
||||
cookies = None,
|
||||
proxy=None,
|
||||
cookies=None,
|
||||
) -> None:
|
||||
self.proxy = proxy
|
||||
self.chat_hub: _ChatHub = _ChatHub(
|
||||
@@ -636,8 +638,8 @@ class Chatbot:
|
||||
|
||||
@staticmethod
|
||||
async def create(
|
||||
proxy = None,
|
||||
cookies = None,
|
||||
proxy=None,
|
||||
cookies=None,
|
||||
):
|
||||
self = Chatbot.__new__(Chatbot)
|
||||
self.proxy = proxy
|
||||
@@ -654,7 +656,7 @@ class Chatbot:
|
||||
wss_link: str = "wss://sydney.bing.com/sydney/ChatHub",
|
||||
conversation_style: CONVERSATION_STYLE_TYPE = None,
|
||||
options: dict = None,
|
||||
webpage_context = None,
|
||||
webpage_context=None,
|
||||
search_result: bool = False,
|
||||
) -> dict:
|
||||
"""
|
||||
@@ -680,7 +682,7 @@ class Chatbot:
|
||||
conversation_style: CONVERSATION_STYLE_TYPE = None,
|
||||
raw: bool = False,
|
||||
options: dict = None,
|
||||
webpage_context = None,
|
||||
webpage_context=None,
|
||||
search_result: bool = False,
|
||||
) -> Generator[str, None, None]:
|
||||
"""
|
||||
|
||||
在新工单中引用
屏蔽一个用户