Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/main'
Browse files Browse the repository at this point in the history
  • Loading branch information
bentwnghk committed Sep 19, 2024
2 parents 889402b + 720c23d commit 953e49c
Show file tree
Hide file tree
Showing 13 changed files with 83 additions and 49 deletions.
12 changes: 6 additions & 6 deletions ChuanhuChatbot.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ def create_new_model():
historySearchTextbox = gr.Textbox(show_label=False, container=False, placeholder=i18n(
"搜索(支持正则)..."), lines=1, elem_id="history-search-tb")
with gr.Column(min_width=52, scale=1, elem_id="gr-history-header-btns"):
uploadFileBtn = gr.UploadButton(
interactive=True, label="", file_types=[".json"], elem_id="gr-history-upload-btn")
uploadHistoryBtn = gr.UploadButton(
interactive=True, label="", file_types=[".json"], elem_id="gr-history-upload-btn", type="binary")
historyRefreshBtn = gr.Button("", elem_id="gr-history-refresh-btn")


Expand Down Expand Up @@ -575,7 +575,7 @@ def create_greeting(request: gr.Request):

auto_name_chat_history_args = dict(
fn=auto_name_chat_history,
inputs=[current_model, name_chat_method, user_question, chatbot, single_turn_checkbox],
inputs=[current_model, name_chat_method, user_question, single_turn_checkbox],
outputs=[historySelectList],
show_progress=False,
)
Expand Down Expand Up @@ -708,8 +708,8 @@ def create_greeting(request: gr.Request):
js='(a,b)=>{return clearChatbot(a,b);}',
)
historySelectList.select(**load_history_from_file_args)
uploadFileBtn.upload(upload_chat_history, [current_model, uploadFileBtn], [
saveFileName, systemPromptTxt, chatbot, single_turn_checkbox, temperature_slider, top_p_slider, n_choices_slider, stop_sequence_txt, max_context_length_slider, max_generation_slider, presence_penalty_slider, frequency_penalty_slider, logit_bias_txt, user_identifier_txt, use_streaming_checkbox]).then(**refresh_history_args)
uploadHistoryBtn.upload(upload_chat_history, [current_model, uploadHistoryBtn], [
saveFileName, systemPromptTxt, chatbot, single_turn_checkbox, temperature_slider, top_p_slider, n_choices_slider, stop_sequence_txt, max_context_length_slider, max_generation_slider, presence_penalty_slider, frequency_penalty_slider, logit_bias_txt, user_identifier_txt, use_streaming_checkbox, historySelectList]).then(**refresh_history_args)
historyDownloadBtn.click(None, [
user_name, historySelectList], None, js='(a,b)=>{return downloadHistory(a,b,".json");}')
historyMarkdownDownloadBtn.click(None, [
Expand Down Expand Up @@ -781,7 +781,7 @@ def create_greeting(request: gr.Request):
# Invisible elements
updateChuanhuBtn.click(
update_chuanhu,
[],
[user_name],
[status_display],
show_progress=True,
)
Expand Down
1 change: 1 addition & 0 deletions config_example.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
//== 基础配置 ==
"language": "auto", // 界面语言,可选"auto", "zh_CN", "en_US", "ja_JP", "ko_KR", "sv_SE", "ru_RU", "vi_VN"
"users": [], // 用户列表,[["用户名1", "密码1"], ["用户名2", "密码2"], ...]
"admin_list": [], // 管理员列表,["用户名1", "用户名2", ...] 只有管理员可以重启服务
"local_embedding": false, //是否在本地编制索引
"hide_history_when_not_logged_in": false, //未登录情况下是否不展示对话历史
"check_update": true, //是否启用检查更新
Expand Down
3 changes: 2 additions & 1 deletion locale/en_US.json
Original file line number Diff line number Diff line change
Expand Up @@ -280,5 +280,6 @@
"chuanhu_question_4": "Any new trends on TikTok?",
"gpt4o_description": "OpenAI's most advanced, multimodal flagship model that’s cheaper and faster than GPT-4 Turbo.",
"gpt4omini_description": "OpenAI's affordable and intelligent small model for fast, lightweight tasks.",
"o1_description": "The o1 series of large language models are trained with reinforcement learning to perform complex reasoning. o1 models think before they answer, producing a long internal chain of thought before responding to the user."
"o1_description": "The o1 series of large language models are trained with reinforcement learning to perform complex reasoning. o1 models think before they answer, producing a long internal chain of thought before responding to the user.",
"no_permission_to_update_description": "You do not have permission to update. Please contact the administrator. The administrator's configuration method is to add the username to the admin_list in the configuration file config.json."
}
3 changes: 2 additions & 1 deletion locale/ja_JP.json
Original file line number Diff line number Diff line change
Expand Up @@ -194,5 +194,6 @@
"🗑️ 删除最新对话": "🗑️ 最新の会話削除",
"🗑️ 删除最旧对话": "🗑️ 最古の会話削除",
"🧹 新的对话": "🧹 新しい会話",
"o1_description": "o1シリーズの大規模言語モデルは、複雑な推論を行うために強化学習で訓練されています。o1モデルは回答する前に考え、ユーザーに応答する前に長い内部思考の連鎖を生成します。"
"o1_description": "o1シリーズの大規模言語モデルは、複雑な推論を行うために強化学習で訓練されています。o1モデルは回答する前に考え、ユーザーに応答する前に長い内部思考の連鎖を生成します。",
"no_permission_to_update_description": "アップデートの権限がありません。 管理者に連絡してください。 管理者の設定は、設定ファイルconfig.jsonのadmin_listにユーザー名を追加することで行います。"
}
3 changes: 2 additions & 1 deletion locale/ko_KR.json
Original file line number Diff line number Diff line change
Expand Up @@ -193,5 +193,6 @@
"🔙 恢复默认网络设置": "🔙 네트워크 설정 초기화",
"🗑️ 删除最新对话": "🗑️ 최신 대화 삭제",
"🗑️ 删除最旧对话": "🗑️ 가장 오래된 대화 삭제",
"🧹 新的对话": "🧹 새로운 대화"
"🧹 新的对话": "🧹 새로운 대화",
"no_permission_to_update_description": "업데이트할 수 있는 권한이 없습니다. 관리자에게 문의하세요. 관리자는 구성 파일 config.json의 admin_list에 사용자 아이디를 추가하여 구성합니다."
}
3 changes: 2 additions & 1 deletion locale/ru_RU.json
Original file line number Diff line number Diff line change
Expand Up @@ -193,5 +193,6 @@
"🔙 恢复默认网络设置": "🔙 Восстановить настройки сети по умолчанию",
"🗑️ 删除最新对话": "🗑️ Удалить последний диалог",
"🗑️ 删除最旧对话": "🗑️ Удалить старейший диалог",
"🧹 新的对话": "🧹 Новый диалог"
"🧹 新的对话": "🧹 Новый диалог",
"no_permission_to_update_description": "У вас нет разрешения на обновление. Пожалуйста, свяжитесь с администратором. Администратор настраивается путем добавления имени пользователя в список admin_list в файле config.json."
}
3 changes: 2 additions & 1 deletion locale/sv_SE.json
Original file line number Diff line number Diff line change
Expand Up @@ -193,5 +193,6 @@
"🔙 恢复默认网络设置": "🔙 Återställ standardnätverksinställningar+",
"🗑️ 删除最新对话": "🗑️ Ta bort senaste dialogen",
"🗑️ 删除最旧对话": "🗑️ Ta bort äldsta dialogen",
"🧹 新的对话": "🧹 Ny Dialog"
"🧹 新的对话": "🧹 Ny Dialog",
"no_permission_to_update_description": "Du har inte behörighet att uppdatera. Vänligen kontakta administratören. Administratören konfigureras genom att lägga till användarnamnet i admin_list i konfigurationsfilen config.json."
}
3 changes: 2 additions & 1 deletion locale/vi_VN.json
Original file line number Diff line number Diff line change
Expand Up @@ -193,5 +193,6 @@
"🔙 恢复默认网络设置": "🔙 Khôi phục cài đặt mạng mặc định",
"🗑️ 删除最新对话": "🗑️ Xóa cuộc trò chuyện mới nhất",
"🗑️ 删除最旧对话": "🗑️ Xóa cuộc trò chuyện cũ nhất",
"🧹 新的对话": "🧹 Cuộc trò chuyện mới"
"🧹 新的对话": "🧹 Cuộc trò chuyện mới",
"no_permission_to_update_description": "Bạn không có quyền cập nhật. Vui lòng liên hệ với quản trị viên. Cách cấu hình của quản trị viên là thêm tên người dùng vào danh sách admin_list trong tệp cấu hình config.json."
}
3 changes: 2 additions & 1 deletion locale/zh_CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,6 @@
"chuanhu_question_4": "TikTok 上有什么新梗?",
"gpt4o_description": "OpenAI 的最先进的多模态旗舰模型,比 GPT-4 Turbo 更便宜、更快。",
"gpt4omini_description": "OpenAI 的经济实惠且智能的小型模型,适用于快速、轻量级任务。",
"o1_description": "o1 系列的大型语言模型通过强化学习训练,能够执行复杂的推理任务。o1 模型在回答之前会进行思考,产生一长串内部思维链,然后再回应用户。"
"o1_description": "o1 系列的大型语言模型通过强化学习训练,能够执行复杂的推理任务。o1 模型在回答之前会进行思考,产生一长串内部思维链,然后再回应用户。",
"no_permission_to_update_description": "你没有权限更新。请联系管理员。管理员的配置方式为在配置文件 config.json 中的 admin_list 中添加用户名。"
}
1 change: 1 addition & 0 deletions modules/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ def load_config_to_environ(key_list):
shared.state.set_api_key_queue(api_key_list)

auth_list = config.get("users", []) # 实际上是使用者的列表
admin_list = config.get("admin_list", []) # 管理员列表
authflag = len(auth_list) > 0 # 是否开启认证的状态值,改为判断auth_list长度

# 处理自定义的api_host,优先读环境变量的配置,如果存在则自动装配
Expand Down
6 changes: 3 additions & 3 deletions modules/models/OpenAIVision.py
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ def _single_query_at_once(self, history, temperature=1.0):

return response

def auto_name_chat_history(self, name_chat_method, user_question, chatbot, single_turn_checkbox):
def auto_name_chat_history(self, name_chat_method, user_question, single_turn_checkbox):
if len(self.history) == 2 and not single_turn_checkbox and not hide_history_when_not_logged_in:
user_question = self.history[0]["content"]
if name_chat_method == i18n("模型自动总结(消耗tokens)"):
Expand All @@ -307,10 +307,10 @@ def auto_name_chat_history(self, name_chat_method, user_question, chatbot, singl
except Exception as e:
logging.info(f"自动命名失败。{e}")
filename = replace_special_symbols(user_question)[:16] + ".json"
return self.rename_chat_history(filename, chatbot)
return self.rename_chat_history(filename)
elif name_chat_method == i18n("第一条提问"):
filename = replace_special_symbols(user_question)[:16] + ".json"
return self.rename_chat_history(filename, chatbot)
return self.rename_chat_history(filename)
else:
return gr.update()
else:
Expand Down
55 changes: 32 additions & 23 deletions modules/models/base_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -758,7 +758,6 @@ def retry(
iter = self.predict(
inputs,
chatbot,
stream=self.stream,
use_websearch=use_websearch,
files=files,
reply_language=reply_language,
Expand Down Expand Up @@ -944,7 +943,7 @@ def token_message(self, token_lst=None):
+ f"{token_sum} tokens"
)

def rename_chat_history(self, filename, chatbot):
def rename_chat_history(self, filename):
if filename == "":
return gr.update()
if not filename.endswith(".json"):
Expand All @@ -965,14 +964,14 @@ def rename_chat_history(self, filename, chatbot):
return init_history_list(self.user_name)

def auto_name_chat_history(
self, name_chat_method, user_question, chatbot, single_turn_checkbox
self, name_chat_method, user_question, single_turn_checkbox
):
if len(self.history) == 2 and not single_turn_checkbox:
user_question = self.history[0]["content"]
if type(user_question) == list:
user_question = user_question[0]["text"]
filename = replace_special_symbols(user_question)[:16] + ".json"
return self.rename_chat_history(filename, chatbot)
return self.rename_chat_history(filename)
else:
return gr.update()

Expand All @@ -987,28 +986,37 @@ def export_markdown(self, filename, chatbot):
filename += ".md"
save_file(filename, self)

def upload_chat_history(self, new_history_file_content=None):
logging.debug(f"{self.user_name} 加载对话历史中……")
if new_history_file_content is not None:
if isinstance(new_history_file_content, bytes):
try:
# Try to parse the content as JSON
json_content = json.loads(new_history_file_content.decode('utf-8'))

# If successful, save the content to a file
new_history_filename = new_auto_history_filename(self.user_name)
new_history_file_path = os.path.join(HISTORY_DIR, self.user_name, new_history_filename)

# Ensure the directory exists
os.makedirs(os.path.dirname(new_history_file_path), exist_ok=True)

# Write the content to the file
with open(new_history_file_path, 'w', encoding='utf-8') as f:
json.dump(json_content, f, ensure_ascii=False, indent=2)

self.history_file_path = new_history_filename
logging.info(f"History file uploaded and saved as {new_history_filename}")
except json.JSONDecodeError:
logging.error("Uploaded content is not valid JSON. Using default history.")
else:
logging.warning("Unexpected type for new_history_file_content. Using default history.")
return *self.load_chat_history(new_history_file_path), init_history_list(self.user_name)

def load_chat_history(self, new_history_file_path=None):
logging.debug(f"{self.user_name} 加载对话历史中……")
if new_history_file_path is not None:
if type(new_history_file_path) != str:
# copy file from new_history_file_path.name to os.path.join(HISTORY_DIR, self.user_name)
new_history_file_path = new_history_file_path.name
target_path = os.path.join(HISTORY_DIR, self.user_name, new_history_file_path)
# Check if the file is in the history directory
assert os.path.realpath(new_history_file_path).startswith(os.path.realpath(HISTORY_DIR))
assert os.path.realpath(target_path).startswith(os.path.realpath(HISTORY_DIR))
assert self.user_name in [i[0] for i in auth_list]
shutil.copyfile(
new_history_file_path,
os.path.join(
HISTORY_DIR,
self.user_name,
os.path.basename(new_history_file_path),
),
)
self.history_file_path = os.path.basename(new_history_file_path)
else:
self.history_file_path = new_history_file_path
self.history_file_path = new_history_file_path
try:
if self.history_file_path == os.path.basename(self.history_file_path):
history_file_path = os.path.join(
Expand Down Expand Up @@ -1039,6 +1047,7 @@ def load_chat_history(self, new_history_file_path=None):
-len(saved_json["chatbot"]) :
]
logging.info(f"Trimmed history: {saved_json['history']}")

# Sanitize chatbot
saved_json["chatbot"] = remove_html_tags(saved_json["chatbot"])
logging.debug(f"{self.user_name} 加载对话历史完毕")
Expand Down
36 changes: 26 additions & 10 deletions modules/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

from modules.presets import *
from . import shared
from modules.config import retrieve_proxy, hide_history_when_not_logged_in
from modules.config import retrieve_proxy, hide_history_when_not_logged_in, admin_list

if TYPE_CHECKING:
from typing import TypedDict
Expand Down Expand Up @@ -99,7 +99,7 @@ def export_markdown(current_model, *args):


def upload_chat_history(current_model, *args):
return current_model.load_chat_history(*args)
return current_model.upload_chat_history(*args)


def set_token_upper_limit(current_model, *args):
Expand Down Expand Up @@ -245,13 +245,27 @@ def convert_mdtext(md_text): # deprecated

def remove_html_tags(data):
def clean_text(text):
# Remove all HTML tags
cleaned = re.sub(r'<[^>]+>', '', text)
# Remove any remaining HTML entities
cleaned = re.sub(r'&[#\w]+;', '', cleaned)
# Remove extra whitespace and newlines
cleaned = re.sub(r'\s+', ' ', cleaned)
return cleaned.strip()
# Regular expression to match code blocks, including all newlines
code_block_pattern = r'(```[\s\S]*?```)'

# Split the text into code blocks and non-code blocks
parts = re.split(code_block_pattern, text)

cleaned_parts = []
for part in parts:
if part.startswith('```') and part.endswith('```'):
# This is a code block, keep it exactly as is
cleaned_parts.append(part)
else:
# This is not a code block, remove HTML tags
# Remove all HTML tags
cleaned = re.sub(r'<[^>]+>', '', part)
# Remove any remaining HTML entities
cleaned = re.sub(r'&[#\w]+;', '', cleaned)
cleaned_parts.append(cleaned) # Don't strip here to preserve newlines

# Join the cleaned parts back together
return ''.join(cleaned_parts)

return [
[clean_text(item) for item in sublist]
Expand Down Expand Up @@ -727,7 +741,9 @@ def transfer_input(inputs):
)


def update_chuanhu():
def update_chuanhu(username):
if username not in admin_list:
return gr.Markdown(value=i18n("no_permission_to_update_description"))
from .repo import background_update

print("[Updater] Trying to update...")
Expand Down

0 comments on commit 953e49c

Please sign in to comment.