From c1dbdcff18bc76ab14b80c3816f82b773bae2809 Mon Sep 17 00:00:00 2001 From: DrSmoothl <1787882683@qq.com> Date: Mon, 17 Mar 2025 20:06:04 +0800 Subject: [PATCH 01/13] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E5=85=A8=E7=90=83?= =?UTF-8?q?=E5=9C=A8=E7=BA=BF=E6=95=B0=E9=87=8F=E5=B1=95=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- webui.py | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/webui.py b/webui.py index f0966233..717ddc1e 100644 --- a/webui.py +++ b/webui.py @@ -100,6 +100,44 @@ MODEL_PROVIDER_LIST = [ #env读取保存结束 #============================================== +#获取在线麦麦数量 +import requests + +def get_online_maimbot(url="http://hyybuth.xyz:10058/api/clients/details", timeout=10): + """ + 获取在线客户端详细信息。 + + 参数: + url (str): API 请求地址,默认值为 "http://hyybuth.xyz:10058/api/clients/details"。 + timeout (int): 请求超时时间,默认值为 10 秒。 + + 返回: + dict: 解析后的 JSON 数据。 + + 异常: + 如果请求失败或数据格式不正确,将返回 None 并记录错误信息。 + """ + try: + response = requests.get(url, timeout=timeout) + # 检查 HTTP 响应状态码是否为 200 + if response.status_code == 200: + # 尝试解析 JSON 数据 + return response.json() + else: + logger.error(f"请求失败,状态码: {response.status_code}") + return None + except requests.exceptions.Timeout: + logger.error("请求超时,请检查网络连接或增加超时时间。") + return None + except requests.exceptions.ConnectionError: + logger.error("连接错误,请检查网络或API地址是否正确。") + return None + except ValueError: # 包括 json.JSONDecodeError + logger.error("无法解析返回的JSON数据,请检查API返回内容。") + return None + +online_maimbot_data = get_online_maimbot() + #============================================== #env环境文件中插件修改更新函数 def add_item(new_item, current_list): @@ -399,6 +437,10 @@ with gr.Blocks(title="MaimBot配置文件编辑") as app: ### 欢迎使用由墨梓柒MotricSeven编写的MaimBot配置文件编辑器\n """ ) + gr.Markdown( + value="## 全球在线MaiMBot数量: " + str(online_maimbot_data['online_clients']) + ) + gr.Markdown( value="### 配置文件版本:" + config_data["inner"]["version"] ) From 300a0d4129cc97a673ad9036dbd33c16c82a4f2c Mon Sep 17 00:00:00 2001 From: Ark-Hakobune <752780039@qq.com> Date: Mon, 17 Mar 2025 22:51:21 +0800 Subject: [PATCH 02/13] =?UTF-8?q?=E9=A2=9C=E6=96=87=E5=AD=97=E5=88=86?= =?UTF-8?q?=E5=89=B2=E9=97=AE=E9=A2=98=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- MaiLauncher.bat | 1272 ++++++++++++++++++------------------- src/plugins/chat/utils.py | 56 +- 2 files changed, 691 insertions(+), 637 deletions(-) diff --git a/MaiLauncher.bat b/MaiLauncher.bat index 7b876bd3..766bfbfb 100644 --- a/MaiLauncher.bat +++ b/MaiLauncher.bat @@ -1,636 +1,636 @@ -@echo off -@setlocal enabledelayedexpansion -@chcp 936 - -@REM ð汾 -set "VERSION=1.0" - -title Bot̨ v%VERSION% - -@REM PythonGit -set "_root=%~dp0" -set "_root=%_root:~0,-1%" -cd "%_root%" - - -:search_python -cls -if exist "%_root%\python" ( - set "PYTHON_HOME=%_root%\python" -) else if exist "%_root%\venv" ( - call "%_root%\venv\Scripts\activate.bat" - set "PYTHON_HOME=%_root%\venv\Scripts" -) else ( - echo ԶPython... - - where python >nul 2>&1 - if %errorlevel% equ 0 ( - for /f "delims=" %%i in ('where python') do ( - echo %%i | findstr /i /c:"!LocalAppData!\Microsoft\WindowsApps\python.exe" >nul - if errorlevel 1 ( - echo ҵPython%%i - set "py_path=%%i" - goto :validate_python - ) - ) - ) - set "search_paths=%ProgramFiles%\Git*;!LocalAppData!\Programs\Python\Python*" - for /d %%d in (!search_paths!) do ( - if exist "%%d\python.exe" ( - set "py_path=%%d\python.exe" - goto :validate_python - ) - ) - echo ûҵPython,Ҫװ? - set /p pyinstall_confirm="(Y/n): " - if /i "!pyinstall_confirm!"=="Y" ( - cls - echo ڰװPython... - winget install --id Python.Python.3.13 -e --accept-package-agreements --accept-source-agreements - if %errorlevel% neq 0 ( - echo װʧܣֶװPython - start https://www.python.org/downloads/ - exit /b - ) - echo װɣ֤Python... - goto search_python - - ) else ( - echo ȡװPython˳... - pause >nul - exit /b - ) - - echo δҵõPython - exit /b 1 - - :validate_python - "!py_path!" --version >nul 2>&1 - if %errorlevel% neq 0 ( - echo ЧPython%py_path% - exit /b 1 - ) - - :: ȡװĿ¼ - for %%i in ("%py_path%") do set "PYTHON_HOME=%%~dpi" - set "PYTHON_HOME=%PYTHON_HOME:~0,-1%" -) -if not exist "%PYTHON_HOME%\python.exe" ( - echo Python·֤ʧܣ%PYTHON_HOME% - echo Pythonװ·Ƿpython.exeļ - exit /b 1 -) -echo ɹPython·%PYTHON_HOME% - - - -:search_git -cls -if exist "%_root%\tools\git\bin" ( - set "GIT_HOME=%_root%\tools\git\bin" -) else ( - echo ԶGit... - - where git >nul 2>&1 - if %errorlevel% equ 0 ( - for /f "delims=" %%i in ('where git') do ( - set "git_path=%%i" - goto :validate_git - ) - ) - echo ɨ賣װ·... - set "search_paths=!ProgramFiles!\Git\cmd" - for /f "tokens=*" %%d in ("!search_paths!") do ( - if exist "%%d\git.exe" ( - set "git_path=%%d\git.exe" - goto :validate_git - ) - ) - echo ûҵGitҪװ - set /p confirm="(Y/N): " - if /i "!confirm!"=="Y" ( - cls - echo ڰװGit... - set "custom_url=https://ghfast.top/https://github.com/git-for-windows/git/releases/download/v2.48.1.windows.1/Git-2.48.1-64-bit.exe" - - set "download_path=%TEMP%\Git-Installer.exe" - - echo Gitװ... - curl -L -o "!download_path!" "!custom_url!" - - if exist "!download_path!" ( - echo سɹʼװGit... - start /wait "" "!download_path!" /SILENT /NORESTART - ) else ( - echo ʧܣֶװGit - start https://git-scm.com/download/win - exit /b - ) - - del "!download_path!" - echo ʱļ - - echo װɣ֤Git... - where git >nul 2>&1 - if %errorlevel% equ 0 ( - for /f "delims=" %%i in ('where git') do ( - set "git_path=%%i" - goto :validate_git - ) - goto :search_git - - ) else ( - echo װɣδҵGitֶװGit - start https://git-scm.com/download/win - exit /b - ) - - ) else ( - echo ȡװGit˳... - pause >nul - exit /b - ) - - echo δҵõGit - exit /b 1 - - :validate_git - "%git_path%" --version >nul 2>&1 - if %errorlevel% neq 0 ( - echo ЧGit%git_path% - exit /b 1 - ) - - :: ȡװĿ¼ - for %%i in ("%git_path%") do set "GIT_HOME=%%~dpi" - set "GIT_HOME=%GIT_HOME:~0,-1%" -) - -:search_mongodb -cls -sc query | findstr /i "MongoDB" >nul -if !errorlevel! neq 0 ( - echo MongoDBδУǷз - set /p confirm="Ƿ(Y/N): " - if /i "!confirm!"=="Y" ( - echo ڳMongoDB... - powershell -Command "Start-Process -Verb RunAs cmd -ArgumentList '/c net start MongoDB'" - echo ڵȴMongoDB... - echo ȴ... - timeout /t 30 >nul - sc query | findstr /i "MongoDB" >nul - if !errorlevel! neq 0 ( - echo MongoDBʧܣûаװҪװ - set /p install_confirm="װ(Y/N): " - if /i "!install_confirm!"=="Y" ( - echo ڰװMongoDB... - winget install --id MongoDB.Server -e --accept-package-agreements --accept-source-agreements - echo װɣMongoDB... - net start MongoDB - if !errorlevel! neq 0 ( - echo MongoDBʧܣֶ - exit /b - ) else ( - echo MongoDBѳɹ - ) - ) else ( - echo ȡװMongoDB˳... - pause >nul - exit /b - ) - ) - ) else ( - echo "棺MongoDBδУMaiMBot޷ݿ⣡" - ) -) else ( - echo MongoDB -) - -@REM set "GIT_HOME=%_root%\tools\git\bin" -set "PATH=%PYTHON_HOME%;%GIT_HOME%;%PATH%" - -:install_maim -if not exist "!_root!\bot.py" ( - cls - echo ƺûаװBotҪװڵǰĿ¼ - set /p confirm="(Y/N): " - if /i "!confirm!"=="Y" ( - echo ҪʹGit - set /p proxy_confirm="(Y/N): " - if /i "!proxy_confirm!"=="Y" ( - echo ڰװBot... - git clone https://ghfast.top/https://github.com/SengokuCola/MaiMBot - ) else ( - echo ڰװBot... - git clone https://github.com/SengokuCola/MaiMBot - ) - xcopy /E /H /I MaiMBot . >nul 2>&1 - rmdir /s /q MaiMBot - git checkout main-fix - - echo װɣڰװ... - python -m pip config set global.index-url https://mirrors.aliyun.com/pypi/simple - python -m pip install virtualenv - python -m virtualenv venv - call venv\Scripts\activate.bat - python -m pip install -r requirements.txt - - echo װɣҪ༭ļ - set /p edit_confirm="(Y/N): " - if /i "!edit_confirm!"=="Y" ( - goto config_menu - ) else ( - echo ȡ༭ļ˵... - ) - ) -) - - -@REM gitȡǰ֧ڱ -for /f "delims=" %%b in ('git symbolic-ref --short HEAD 2^>nul') do ( - set "BRANCH=%%b" -) - -@REM ݲַ֧֧ͬʹòͬɫ -echo ֧: %BRANCH% -if "!BRANCH!"=="main" ( - set "BRANCH_COLOR=" -) else if "!BRANCH!"=="main-fix" ( - set "BRANCH_COLOR=" -@REM ) else if "%BRANCH%"=="stable-dev" ( -@REM set "BRANCH_COLOR=" -) else ( - set "BRANCH_COLOR=" -) - -@REM endlocal & set "BRANCH_COLOR=%BRANCH_COLOR%" - -:check_is_venv -echo ڼ⻷״̬... -if exist "%_root%\config\no_venv" ( - echo ⵽no_venv,⻷ - goto menu -) - -:: -if defined VIRTUAL_ENV ( - goto menu -) - -echo ===================================== -echo ⻷⾯棺 -echo ǰʹϵͳPython·!PYTHON_HOME! -echo δ⵽⻷ - -:env_interaction -echo ===================================== -echo ѡ -echo 1 - Venv⻷ -echo 2 - /Conda⻷ -echo 3 - ʱμ -echo 4 - ⻷ -set /p choice="ѡ(1-4): " - -if "!choice!"=="4" ( - echo Ҫ⻷ - set /p no_venv_confirm="(Y/N): ....." - if /i "!no_venv_confirm!"=="Y" ( - echo 1 > "%_root%\config\no_venv" - echo Ѵno_venvļ - pause >nul - goto menu - ) else ( - echo ȡ⻷飬... - pause >nul - goto env_interaction - ) -) - -if "!choice!"=="3" ( - echo 棺ʹϵͳܵͻ - timeout /t 2 >nul - goto menu -) - -if "!choice!"=="2" goto handle_conda -if "!choice!"=="1" goto handle_venv - -echo Ч룬1-4֮ -timeout /t 2 >nul -goto env_interaction - -:handle_venv -python -m pip config set global.index-url https://mirrors.aliyun.com/pypi/simple -echo ڳʼVenv... -python -m pip install virtualenv || ( - echo װʧܣ룺!errorlevel! - pause - goto env_interaction -) -echo ⻷venv - python -m virtualenv venv || ( - echo ʧܣ룺!errorlevel! - pause - goto env_interaction -) - -call venv\Scripts\activate.bat -echo ѼVenv -echo Ҫװ -set /p install_confirm="(Y/N): " -if /i "!install_confirm!"=="Y" ( - goto update_dependencies -) -goto menu - -:handle_conda -where conda >nul 2>&1 || ( - echo δ⵽condaԭ - echo 1. δװMiniconda - echo 2. conda쳣 - timeout /t 10 >nul - goto env_interaction -) - -:conda_menu -echo ѡConda -echo 1 - » -echo 2 - л -echo 3 - ϼ˵ -set /p choice="ѡ(1-3): " - -if "!choice!"=="3" goto env_interaction -if "!choice!"=="2" goto activate_conda -if "!choice!"=="1" goto create_conda - -echo Ч룬1-3֮ -timeout /t 2 >nul -goto conda_menu - -:create_conda -set /p "CONDA_ENV=»ƣ" -if "!CONDA_ENV!"=="" ( - echo ƲΪգ - goto create_conda -) -conda create -n !CONDA_ENV! python=3.13 -y || ( - echo ʧܣ룺!errorlevel! - timeout /t 10 >nul - goto conda_menu -) -goto activate_conda - -:activate_conda -set /p "CONDA_ENV=ҪĻƣ" -call conda activate !CONDA_ENV! || ( - echo ʧܣԭ - echo 1. - echo 2. conda쳣 - pause - goto conda_menu -) -echo ɹconda!CONDA_ENV! -echo Ҫװ -set /p install_confirm="(Y/N): " -if /i "!install_confirm!"=="Y" ( - goto update_dependencies -) -:menu -@chcp 936 -cls -echo Bot̨ v%VERSION% ǰ֧: %BRANCH_COLOR%%BRANCH% -echo ǰPython: !PYTHON_HOME! -echo ====================== -echo 1. ²Bot (Ĭ) -echo 2. ֱBot -echo 3. ý -echo 4. 湤 -echo 5. ˳ -echo ====================== - -set /p choice="ѡ (1-5)»سѡ: " - -if "!choice!"=="" set choice=1 - -if "!choice!"=="1" goto update_and_start -if "!choice!"=="2" goto start_bot -if "!choice!"=="3" goto config_menu -if "!choice!"=="4" goto tools_menu -if "!choice!"=="5" exit /b - -echo Ч룬1-5֮ -timeout /t 2 >nul -goto menu - -:config_menu -@chcp 936 -cls -if not exist config/bot_config.toml ( - copy /Y "template\bot_config_template.toml" "config\bot_config.toml" - -) -if not exist .env.prod ( - copy /Y "template\.env.prod" ".env.prod" -) - -start python webui.py - -goto menu - - -:tools_menu -@chcp 936 -cls -echo ʱй ǰ֧: %BRANCH_COLOR%%BRANCH% -echo ====================== -echo 1. -echo 2. л֧ -echo 3. õǰ֧ -echo 4. ļ -echo 5. ѧϰµ֪ʶ -echo 6. ֪ʶļ -echo 7. ˵ -echo ====================== - -set /p choice="ѡ: " -if "!choice!"=="1" goto update_dependencies -if "!choice!"=="2" goto switch_branch -if "!choice!"=="3" goto reset_branch -if "!choice!"=="4" goto update_config -if "!choice!"=="5" goto learn_new_knowledge -if "!choice!"=="6" goto open_knowledge_folder -if "!choice!"=="7" goto menu - -echo Ч룬1-6֮ -timeout /t 2 >nul -goto tools_menu - -:update_dependencies -cls -echo ڸ... -python -m pip config set global.index-url https://mirrors.aliyun.com/pypi/simple -python.exe -m pip install -r requirements.txt - -echo ɣع˵... -pause -goto tools_menu - -:switch_branch -cls -echo л֧... -echo ǰ֧: %BRANCH% -@REM echo ÷֧: main, debug, stable-dev -echo 1. лmain -echo 2. лmain-fix -echo Ҫлķ֧: -set /p branch_name="֧: " -if "%branch_name%"=="" set branch_name=main -if "%branch_name%"=="main" ( - set "BRANCH_COLOR=" -) else if "%branch_name%"=="main-fix" ( - set "BRANCH_COLOR=" -@REM ) else if "%branch_name%"=="stable-dev" ( -@REM set "BRANCH_COLOR=" -) else if "%branch_name%"=="1" ( - set "BRANCH_COLOR=" - set "branch_name=main" -) else if "%branch_name%"=="2" ( - set "BRANCH_COLOR=" - set "branch_name=main-fix" -) else ( - echo Чķ֧, - timeout /t 2 >nul - goto switch_branch -) - -echo л֧ %branch_name%... -git checkout %branch_name% -echo ֧лɣǰ֧: %BRANCH_COLOR%%branch_name% -set "BRANCH=%branch_name%" -echo ع˵... -pause >nul -goto tools_menu - - -:reset_branch -cls -echo õǰ֧... -echo ǰ֧: !BRANCH! -echo ȷҪõǰ֧ -set /p confirm="(Y/N): " -if /i "!confirm!"=="Y" ( - echo õǰ֧... - git reset --hard !BRANCH! - echo ֧ɣع˵... -) else ( - echo ȡõǰ֧ع˵... -) -pause >nul -goto tools_menu - - -:update_config -cls -echo ڸļ... -echo ȷѱҪݣ޸ĵǰļ -echo 밴Yȡ밴... -set /p confirm="(Y/N): " -if /i "!confirm!"=="Y" ( - echo ڸļ... - python.exe config\auto_update.py - echo ļɣع˵... -) else ( - echo ȡļع˵... -) -pause >nul -goto tools_menu - -:learn_new_knowledge -cls -echo ѧϰµ֪ʶ... -echo ȷѱҪݣ޸ĵǰ֪ʶ⡣ -echo 밴Yȡ밴... -set /p confirm="(Y/N): " -if /i "!confirm!"=="Y" ( - echo ѧϰµ֪ʶ... - python.exe src\plugins\zhishi\knowledge_library.py - echo ѧϰɣع˵... -) else ( - echo ȡѧϰµ֪ʶ⣬ع˵... -) -pause >nul -goto tools_menu - -:open_knowledge_folder -cls -echo ڴ֪ʶļ... -if exist data\raw_info ( - start explorer data\raw_info -) else ( - echo ֪ʶļвڣ - echo ڴļ... - mkdir data\raw_info - timeout /t 2 >nul -) -goto tools_menu - - -:update_and_start -cls -:retry_git_pull -git pull > temp.log 2>&1 -findstr /C:"detected dubious ownership" temp.log >nul -if %errorlevel% equ 0 ( - echo ⵽ֿȨ⣬Զ޸... - git config --global --add safe.directory "%cd%" - echo ⣬git pull... - del temp.log - goto retry_git_pull -) -del temp.log -echo ڸ... -python -m pip config set global.index-url https://mirrors.aliyun.com/pypi/simple -python -m pip install -r requirements.txt && cls - -echo ǰ: -echo HTTP_PROXY=%HTTP_PROXY% -echo HTTPS_PROXY=%HTTPS_PROXY% - -echo Disable Proxy... -set HTTP_PROXY= -set HTTPS_PROXY= -set no_proxy=0.0.0.0/32 - -REM chcp 65001 -python bot.py -echo. -echo BotֹͣУ˵... -pause >nul -goto menu - -:start_bot -cls -echo ڸ... -python -m pip config set global.index-url https://mirrors.aliyun.com/pypi/simple -python -m pip install -r requirements.txt && cls - -echo ǰ: -echo HTTP_PROXY=%HTTP_PROXY% -echo HTTPS_PROXY=%HTTPS_PROXY% - -echo Disable Proxy... -set HTTP_PROXY= -set HTTPS_PROXY= -set no_proxy=0.0.0.0/32 - -REM chcp 65001 -python bot.py -echo. -echo BotֹͣУ˵... -pause >nul -goto menu - - -:open_dir -start explorer "%cd%" -goto menu +@echo off +@setlocal enabledelayedexpansion +@chcp 936 + +@REM 设置版本号 +set "VERSION=1.0" + +title 麦麦Bot控制台 v%VERSION% + +@REM 设置Python和Git环境变量 +set "_root=%~dp0" +set "_root=%_root:~0,-1%" +cd "%_root%" + + +:search_python +cls +if exist "%_root%\python" ( + set "PYTHON_HOME=%_root%\python" +) else if exist "%_root%\venv" ( + call "%_root%\venv\Scripts\activate.bat" + set "PYTHON_HOME=%_root%\venv\Scripts" +) else ( + echo 正在自动查找Python解释器... + + where python >nul 2>&1 + if %errorlevel% equ 0 ( + for /f "delims=" %%i in ('where python') do ( + echo %%i | findstr /i /c:"!LocalAppData!\Microsoft\WindowsApps\python.exe" >nul + if errorlevel 1 ( + echo 找到Python解释器:%%i + set "py_path=%%i" + goto :validate_python + ) + ) + ) + set "search_paths=%ProgramFiles%\Git*;!LocalAppData!\Programs\Python\Python*" + for /d %%d in (!search_paths!) do ( + if exist "%%d\python.exe" ( + set "py_path=%%d\python.exe" + goto :validate_python + ) + ) + echo 没有找到Python解释器,要安装吗? + set /p pyinstall_confirm="继续?(Y/n): " + if /i "!pyinstall_confirm!"=="Y" ( + cls + echo 正在安装Python... + winget install --id Python.Python.3.13 -e --accept-package-agreements --accept-source-agreements + if %errorlevel% neq 0 ( + echo 安装失败,请手动安装Python + start https://www.python.org/downloads/ + exit /b + ) + echo 安装完成,正在验证Python... + goto search_python + + ) else ( + echo 取消安装Python,按任意键退出... + pause >nul + exit /b + ) + + echo 错误:未找到可用的Python解释器! + exit /b 1 + + :validate_python + "!py_path!" --version >nul 2>&1 + if %errorlevel% neq 0 ( + echo 无效的Python解释器:%py_path% + exit /b 1 + ) + + :: 提取安装目录 + for %%i in ("%py_path%") do set "PYTHON_HOME=%%~dpi" + set "PYTHON_HOME=%PYTHON_HOME:~0,-1%" +) +if not exist "%PYTHON_HOME%\python.exe" ( + echo Python路径验证失败:%PYTHON_HOME% + echo 请检查Python安装路径中是否有python.exe文件 + exit /b 1 +) +echo 成功设置Python路径:%PYTHON_HOME% + + + +:search_git +cls +if exist "%_root%\tools\git\bin" ( + set "GIT_HOME=%_root%\tools\git\bin" +) else ( + echo 正在自动查找Git... + + where git >nul 2>&1 + if %errorlevel% equ 0 ( + for /f "delims=" %%i in ('where git') do ( + set "git_path=%%i" + goto :validate_git + ) + ) + echo 正在扫描常见安装路径... + set "search_paths=!ProgramFiles!\Git\cmd" + for /f "tokens=*" %%d in ("!search_paths!") do ( + if exist "%%d\git.exe" ( + set "git_path=%%d\git.exe" + goto :validate_git + ) + ) + echo 没有找到Git,要安装吗? + set /p confirm="继续?(Y/N): " + if /i "!confirm!"=="Y" ( + cls + echo 正在安装Git... + set "custom_url=https://ghfast.top/https://github.com/git-for-windows/git/releases/download/v2.48.1.windows.1/Git-2.48.1-64-bit.exe" + + set "download_path=%TEMP%\Git-Installer.exe" + + echo 正在下载Git安装包... + curl -L -o "!download_path!" "!custom_url!" + + if exist "!download_path!" ( + echo 下载成功,开始安装Git... + start /wait "" "!download_path!" /SILENT /NORESTART + ) else ( + echo 下载失败,请手动安装Git + start https://git-scm.com/download/win + exit /b + ) + + del "!download_path!" + echo 临时文件已清理。 + + echo 安装完成,正在验证Git... + where git >nul 2>&1 + if %errorlevel% equ 0 ( + for /f "delims=" %%i in ('where git') do ( + set "git_path=%%i" + goto :validate_git + ) + goto :search_git + + ) else ( + echo 安装完成,但未找到Git,请手动安装Git + start https://git-scm.com/download/win + exit /b + ) + + ) else ( + echo 取消安装Git,按任意键退出... + pause >nul + exit /b + ) + + echo 错误:未找到可用的Git! + exit /b 1 + + :validate_git + "%git_path%" --version >nul 2>&1 + if %errorlevel% neq 0 ( + echo 无效的Git:%git_path% + exit /b 1 + ) + + :: 提取安装目录 + for %%i in ("%git_path%") do set "GIT_HOME=%%~dpi" + set "GIT_HOME=%GIT_HOME:~0,-1%" +) + +:search_mongodb +cls +sc query | findstr /i "MongoDB" >nul +if !errorlevel! neq 0 ( + echo MongoDB服务未运行,是否尝试运行服务? + set /p confirm="是否启动?(Y/N): " + if /i "!confirm!"=="Y" ( + echo 正在尝试启动MongoDB服务... + powershell -Command "Start-Process -Verb RunAs cmd -ArgumentList '/c net start MongoDB'" + echo 正在等待MongoDB服务启动... + echo 按下任意键跳过等待... + timeout /t 30 >nul + sc query | findstr /i "MongoDB" >nul + if !errorlevel! neq 0 ( + echo MongoDB服务启动失败,可能是没有安装,要安装吗? + set /p install_confirm="继续安装?(Y/N): " + if /i "!install_confirm!"=="Y" ( + echo 正在安装MongoDB... + winget install --id MongoDB.Server -e --accept-package-agreements --accept-source-agreements + echo 安装完成,正在启动MongoDB服务... + net start MongoDB + if !errorlevel! neq 0 ( + echo 启动MongoDB服务失败,请手动启动 + exit /b + ) else ( + echo MongoDB服务已成功启动 + ) + ) else ( + echo 取消安装MongoDB,按任意键退出... + pause >nul + exit /b + ) + ) + ) else ( + echo "警告:MongoDB服务未运行,将导致MaiMBot无法访问数据库!" + ) +) else ( + echo MongoDB服务已运行 +) + +@REM set "GIT_HOME=%_root%\tools\git\bin" +set "PATH=%PYTHON_HOME%;%GIT_HOME%;%PATH%" + +:install_maim +if not exist "!_root!\bot.py" ( + cls + echo 你似乎没有安装麦麦Bot,要安装在当前目录吗? + set /p confirm="继续?(Y/N): " + if /i "!confirm!"=="Y" ( + echo 要使用Git代理下载吗? + set /p proxy_confirm="继续?(Y/N): " + if /i "!proxy_confirm!"=="Y" ( + echo 正在安装麦麦Bot... + git clone https://ghfast.top/https://github.com/SengokuCola/MaiMBot + ) else ( + echo 正在安装麦麦Bot... + git clone https://github.com/SengokuCola/MaiMBot + ) + xcopy /E /H /I MaiMBot . >nul 2>&1 + rmdir /s /q MaiMBot + git checkout main-fix + + echo 安装完成,正在安装依赖... + python -m pip config set global.index-url https://mirrors.aliyun.com/pypi/simple + python -m pip install virtualenv + python -m virtualenv venv + call venv\Scripts\activate.bat + python -m pip install -r requirements.txt + + echo 安装完成,要编辑配置文件吗? + set /p edit_confirm="继续?(Y/N): " + if /i "!edit_confirm!"=="Y" ( + goto config_menu + ) else ( + echo 取消编辑配置文件,按任意键返回主菜单... + ) + ) +) + + +@REM git获取当前分支名并保存在变量里 +for /f "delims=" %%b in ('git symbolic-ref --short HEAD 2^>nul') do ( + set "BRANCH=%%b" +) + +@REM 根据不同分支名给分支名字符串使用不同颜色 +echo 分支名: %BRANCH% +if "!BRANCH!"=="main" ( + set "BRANCH_COLOR=" +) else if "!BRANCH!"=="main-fix" ( + set "BRANCH_COLOR=" +@REM ) else if "%BRANCH%"=="stable-dev" ( +@REM set "BRANCH_COLOR=" +) else ( + set "BRANCH_COLOR=" +) + +@REM endlocal & set "BRANCH_COLOR=%BRANCH_COLOR%" + +:check_is_venv +echo 正在检查虚拟环境状态... +if exist "%_root%\config\no_venv" ( + echo 检测到no_venv,跳过虚拟环境检查 + goto menu +) + +:: 环境检测 +if defined VIRTUAL_ENV ( + goto menu +) + +echo ===================================== +echo 虚拟环境检测警告: +echo 当前使用系统Python路径:!PYTHON_HOME! +echo 未检测到激活的虚拟环境! + +:env_interaction +echo ===================================== +echo 请选择操作: +echo 1 - 创建并激活Venv虚拟环境 +echo 2 - 创建/激活Conda虚拟环境 +echo 3 - 临时跳过本次检查 +echo 4 - 永久跳过虚拟环境检查 +set /p choice="请输入选项(1-4): " + +if "!choice!"=="4" ( + echo 要永久跳过虚拟环境检查吗? + set /p no_venv_confirm="继续?(Y/N): ....." + if /i "!no_venv_confirm!"=="Y" ( + echo 1 > "%_root%\config\no_venv" + echo 已创建no_venv文件 + pause >nul + goto menu + ) else ( + echo 取消跳过虚拟环境检查,按任意键返回... + pause >nul + goto env_interaction + ) +) + +if "!choice!"=="3" ( + echo 警告:使用系统环境可能导致依赖冲突! + timeout /t 2 >nul + goto menu +) + +if "!choice!"=="2" goto handle_conda +if "!choice!"=="1" goto handle_venv + +echo 无效的输入,请输入1-4之间的数字 +timeout /t 2 >nul +goto env_interaction + +:handle_venv +python -m pip config set global.index-url https://mirrors.aliyun.com/pypi/simple +echo 正在初始化Venv环境... +python -m pip install virtualenv || ( + echo 安装环境失败,错误码:!errorlevel! + pause + goto env_interaction +) +echo 创建虚拟环境到:venv + python -m virtualenv venv || ( + echo 环境创建失败,错误码:!errorlevel! + pause + goto env_interaction +) + +call venv\Scripts\activate.bat +echo 已激活Venv环境 +echo 要安装依赖吗? +set /p install_confirm="继续?(Y/N): " +if /i "!install_confirm!"=="Y" ( + goto update_dependencies +) +goto menu + +:handle_conda +where conda >nul 2>&1 || ( + echo 未检测到conda,可能原因: + echo 1. 未安装Miniconda + echo 2. conda配置异常 + timeout /t 10 >nul + goto env_interaction +) + +:conda_menu +echo 请选择Conda操作: +echo 1 - 创建新环境 +echo 2 - 激活已有环境 +echo 3 - 返回上级菜单 +set /p choice="请输入选项(1-3): " + +if "!choice!"=="3" goto env_interaction +if "!choice!"=="2" goto activate_conda +if "!choice!"=="1" goto create_conda + +echo 无效的输入,请输入1-3之间的数字 +timeout /t 2 >nul +goto conda_menu + +:create_conda +set /p "CONDA_ENV=请输入新环境名称:" +if "!CONDA_ENV!"=="" ( + echo 环境名称不能为空! + goto create_conda +) +conda create -n !CONDA_ENV! python=3.13 -y || ( + echo 环境创建失败,错误码:!errorlevel! + timeout /t 10 >nul + goto conda_menu +) +goto activate_conda + +:activate_conda +set /p "CONDA_ENV=请输入要激活的环境名称:" +call conda activate !CONDA_ENV! || ( + echo 激活失败,可能原因: + echo 1. 环境不存在 + echo 2. conda配置异常 + pause + goto conda_menu +) +echo 成功激活conda环境:!CONDA_ENV! +echo 要安装依赖吗? +set /p install_confirm="继续?(Y/N): " +if /i "!install_confirm!"=="Y" ( + goto update_dependencies +) +:menu +@chcp 936 +cls +echo 麦麦Bot控制台 v%VERSION% 当前分支: %BRANCH_COLOR%%BRANCH% +echo 当前Python环境: !PYTHON_HOME! +echo ====================== +echo 1. 更新并启动麦麦Bot (默认) +echo 2. 直接启动麦麦Bot +echo 3. 启动麦麦配置界面 +echo 4. 打开麦麦神奇工具箱 +echo 5. 退出 +echo ====================== + +set /p choice="请输入选项数字 (1-5)并按下回车以选择: " + +if "!choice!"=="" set choice=1 + +if "!choice!"=="1" goto update_and_start +if "!choice!"=="2" goto start_bot +if "!choice!"=="3" goto config_menu +if "!choice!"=="4" goto tools_menu +if "!choice!"=="5" exit /b + +echo 无效的输入,请输入1-5之间的数字 +timeout /t 2 >nul +goto menu + +:config_menu +@chcp 936 +cls +if not exist config/bot_config.toml ( + copy /Y "template\bot_config_template.toml" "config\bot_config.toml" + +) +if not exist .env.prod ( + copy /Y "template\.env.prod" ".env.prod" +) + +start python webui.py + +goto menu + + +:tools_menu +@chcp 936 +cls +echo 麦麦时尚工具箱 当前分支: %BRANCH_COLOR%%BRANCH% +echo ====================== +echo 1. 更新依赖 +echo 2. 切换分支 +echo 3. 重置当前分支 +echo 4. 更新配置文件 +echo 5. 学习新的知识库 +echo 6. 打开知识库文件夹 +echo 7. 返回主菜单 +echo ====================== + +set /p choice="请输入选项数字: " +if "!choice!"=="1" goto update_dependencies +if "!choice!"=="2" goto switch_branch +if "!choice!"=="3" goto reset_branch +if "!choice!"=="4" goto update_config +if "!choice!"=="5" goto learn_new_knowledge +if "!choice!"=="6" goto open_knowledge_folder +if "!choice!"=="7" goto menu + +echo 无效的输入,请输入1-6之间的数字 +timeout /t 2 >nul +goto tools_menu + +:update_dependencies +cls +echo 正在更新依赖... +python -m pip config set global.index-url https://mirrors.aliyun.com/pypi/simple +python.exe -m pip install -r requirements.txt + +echo 依赖更新完成,按任意键返回工具箱菜单... +pause +goto tools_menu + +:switch_branch +cls +echo 正在切换分支... +echo 当前分支: %BRANCH% +@REM echo 可用分支: main, debug, stable-dev +echo 1. 切换到main +echo 2. 切换到main-fix +echo 请输入要切换到的分支: +set /p branch_name="分支名: " +if "%branch_name%"=="" set branch_name=main +if "%branch_name%"=="main" ( + set "BRANCH_COLOR=" +) else if "%branch_name%"=="main-fix" ( + set "BRANCH_COLOR=" +@REM ) else if "%branch_name%"=="stable-dev" ( +@REM set "BRANCH_COLOR=" +) else if "%branch_name%"=="1" ( + set "BRANCH_COLOR=" + set "branch_name=main" +) else if "%branch_name%"=="2" ( + set "BRANCH_COLOR=" + set "branch_name=main-fix" +) else ( + echo 无效的分支名, 请重新输入 + timeout /t 2 >nul + goto switch_branch +) + +echo 正在切换到分支 %branch_name%... +git checkout %branch_name% +echo 分支切换完成,当前分支: %BRANCH_COLOR%%branch_name% +set "BRANCH=%branch_name%" +echo 按任意键返回工具箱菜单... +pause >nul +goto tools_menu + + +:reset_branch +cls +echo 正在重置当前分支... +echo 当前分支: !BRANCH! +echo 确认要重置当前分支吗? +set /p confirm="继续?(Y/N): " +if /i "!confirm!"=="Y" ( + echo 正在重置当前分支... + git reset --hard !BRANCH! + echo 分支重置完成,按任意键返回工具箱菜单... +) else ( + echo 取消重置当前分支,按任意键返回工具箱菜单... +) +pause >nul +goto tools_menu + + +:update_config +cls +echo 正在更新配置文件... +echo 请确保已备份重要数据,继续将修改当前配置文件。 +echo 继续请按Y,取消请按任意键... +set /p confirm="继续?(Y/N): " +if /i "!confirm!"=="Y" ( + echo 正在更新配置文件... + python.exe config\auto_update.py + echo 配置文件更新完成,按任意键返回工具箱菜单... +) else ( + echo 取消更新配置文件,按任意键返回工具箱菜单... +) +pause >nul +goto tools_menu + +:learn_new_knowledge +cls +echo 正在学习新的知识库... +echo 请确保已备份重要数据,继续将修改当前知识库。 +echo 继续请按Y,取消请按任意键... +set /p confirm="继续?(Y/N): " +if /i "!confirm!"=="Y" ( + echo 正在学习新的知识库... + python.exe src\plugins\zhishi\knowledge_library.py + echo 学习完成,按任意键返回工具箱菜单... +) else ( + echo 取消学习新的知识库,按任意键返回工具箱菜单... +) +pause >nul +goto tools_menu + +:open_knowledge_folder +cls +echo 正在打开知识库文件夹... +if exist data\raw_info ( + start explorer data\raw_info +) else ( + echo 知识库文件夹不存在! + echo 正在创建文件夹... + mkdir data\raw_info + timeout /t 2 >nul +) +goto tools_menu + + +:update_and_start +cls +:retry_git_pull +git pull > temp.log 2>&1 +findstr /C:"detected dubious ownership" temp.log >nul +if %errorlevel% equ 0 ( + echo 检测到仓库权限问题,正在自动修复... + git config --global --add safe.directory "%cd%" + echo 已添加例外,正在重试git pull... + del temp.log + goto retry_git_pull +) +del temp.log +echo 正在更新依赖... +python -m pip config set global.index-url https://mirrors.aliyun.com/pypi/simple +python -m pip install -r requirements.txt && cls + +echo 当前代理设置: +echo HTTP_PROXY=%HTTP_PROXY% +echo HTTPS_PROXY=%HTTPS_PROXY% + +echo Disable Proxy... +set HTTP_PROXY= +set HTTPS_PROXY= +set no_proxy=0.0.0.0/32 + +REM chcp 65001 +python bot.py +echo. +echo Bot已停止运行,按任意键返回主菜单... +pause >nul +goto menu + +:start_bot +cls +echo 正在更新依赖... +python -m pip config set global.index-url https://mirrors.aliyun.com/pypi/simple +python -m pip install -r requirements.txt && cls + +echo 当前代理设置: +echo HTTP_PROXY=%HTTP_PROXY% +echo HTTPS_PROXY=%HTTPS_PROXY% + +echo Disable Proxy... +set HTTP_PROXY= +set HTTPS_PROXY= +set no_proxy=0.0.0.0/32 + +REM chcp 65001 +python bot.py +echo. +echo Bot已停止运行,按任意键返回主菜单... +pause >nul +goto menu + + +:open_dir +start explorer "%cd%" +goto menu diff --git a/src/plugins/chat/utils.py b/src/plugins/chat/utils.py index 92eae1b3..b5615ebf 100644 --- a/src/plugins/chat/utils.py +++ b/src/plugins/chat/utils.py @@ -1,6 +1,7 @@ import math import random import time +import re from collections import Counter from typing import Dict, List @@ -253,7 +254,7 @@ def split_into_sentences_w_remove_punctuation(text: str) -> List[str]: # 统一将英文逗号转换为中文逗号 text = text.replace(',', ',') text = text.replace('\n', ' ') - + text, mapping = protect_kaomoji(text) # print(f"处理前的文本: {text}") text_no_1 = '' @@ -292,6 +293,7 @@ def split_into_sentences_w_remove_punctuation(text: str) -> List[str]: current_sentence += ' ' + part new_sentences.append(current_sentence.strip()) sentences = [s for s in new_sentences if s] # 移除空字符串 + sentences = recover_kaomoji(sentences, mapping) # print(f"分割后的句子: {sentences}") sentences_done = [] @@ -446,3 +448,55 @@ def truncate_message(message: str, max_length=20) -> str: if len(message) > max_length: return message[:max_length] + "..." return message + + +def protect_kaomoji(sentence): + """" + 识别并保护句子中的颜文字(含括号与无括号),将其替换为占位符, + 并返回替换后的句子和占位符到颜文字的映射表。 + Args: + sentence (str): 输入的原始句子 + Returns: + tuple: (处理后的句子, {占位符: 颜文字}) + """ + kaomoji_pattern = re.compile( + r'(' + r'[\(\[(【]' # 左括号 + r'[^()\[\]()【】]*?' # 非括号字符(惰性匹配) + r'[^\u4e00-\u9fa5a-zA-Z0-9\s]' # 非中文、非英文、非数字、非空格字符(必须包含至少一个) + r'[^()\[\]()【】]*?' # 非括号字符(惰性匹配) + r'[\)\])】]' # 右括号 + r')' + r'|' + r'(' + r'[▼▽・ᴥω・﹏^><≧≦ ̄`´∀ヮДд︿﹀へ。゚╥╯╰︶︹•⁄]{2,15}' + r')' + ) + + kaomoji_matches = kaomoji_pattern.findall(sentence) + placeholder_to_kaomoji = {} + + for idx, match in enumerate(kaomoji_matches): + kaomoji = match[0] if match[0] else match[1] + placeholder = f'__KAOMOJI_{idx}__' + sentence = sentence.replace(kaomoji, placeholder, 1) + placeholder_to_kaomoji[placeholder] = kaomoji + + return sentence, placeholder_to_kaomoji + + +def recover_kaomoji(sentences, placeholder_to_kaomoji): + """ + 根据映射表恢复句子中的颜文字。 + Args: + sentences (list): 含有占位符的句子列表 + placeholder_to_kaomoji (dict): 占位符到颜文字的映射表 + Returns: + list: 恢复颜文字后的句子列表 + """ + recovered_sentences = [] + for sentence in sentences: + for placeholder, kaomoji in placeholder_to_kaomoji.items(): + sentence = sentence.replace(placeholder, kaomoji) + recovered_sentences.append(sentence) + return recovered_sentences \ No newline at end of file From dbcfe512a46781cc8daf795a6766854dec1a4bfc Mon Sep 17 00:00:00 2001 From: xiruo <1023680301@qq.com> Date: Tue, 18 Mar 2025 09:38:22 +0800 Subject: [PATCH 03/13] =?UTF-8?q?fix(willing):=E4=BF=AE=E5=A4=8Dcfg?= =?UTF-8?q?=E5=8F=98=E9=87=8F=E6=9C=AA=E8=A2=AB=E6=AD=A3=E5=B8=B8=E5=BC=95?= =?UTF-8?q?=E7=94=A8=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/plugins/willing/mode_classical.py | 2 +- src/plugins/willing/mode_custom.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/willing/mode_classical.py b/src/plugins/willing/mode_classical.py index 14ae81c7..81544c20 100644 --- a/src/plugins/willing/mode_classical.py +++ b/src/plugins/willing/mode_classical.py @@ -61,7 +61,7 @@ class WillingManager: reply_probability = 0 if chat_stream.group_info.group_id in config.talk_frequency_down_groups: - reply_probability = reply_probability / 3.5 + reply_probability = reply_probability / config.down_frequency_rate return reply_probability diff --git a/src/plugins/willing/mode_custom.py b/src/plugins/willing/mode_custom.py index 1e17130b..f9f6c4a3 100644 --- a/src/plugins/willing/mode_custom.py +++ b/src/plugins/willing/mode_custom.py @@ -62,7 +62,7 @@ class WillingManager: reply_probability = 0 if chat_stream.group_info.group_id in config.talk_frequency_down_groups: - reply_probability = reply_probability / 3.5 + reply_probability = reply_probability / config.down_frequency_rate if is_mentioned_bot and sender_id == "1026294844": reply_probability = 1 From 8417fd997ec5fd07584b57afc6e3213af08b12c0 Mon Sep 17 00:00:00 2001 From: KawaiiYusora Date: Tue, 18 Mar 2025 16:38:49 +0800 Subject: [PATCH 04/13] =?UTF-8?q?=F0=9F=90=9B=20fix(MaiLauncher.bat):=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20`.env.prod`=20=E6=96=87=E4=BB=B6=E5=A4=8D?= =?UTF-8?q?=E5=88=B6=E8=B7=AF=E5=BE=84=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- MaiLauncher.bat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MaiLauncher.bat b/MaiLauncher.bat index 766bfbfb..619f9c65 100644 --- a/MaiLauncher.bat +++ b/MaiLauncher.bat @@ -430,7 +430,7 @@ if not exist config/bot_config.toml ( ) if not exist .env.prod ( - copy /Y "template\.env.prod" ".env.prod" + copy /Y "template.env" ".env.prod" ) start python webui.py From cabd632bfd9304bf85e287bfc66fb8a83d4f4d61 Mon Sep 17 00:00:00 2001 From: DrSmoothl <1787882683@qq.com> Date: Tue, 18 Mar 2025 20:37:34 +0800 Subject: [PATCH 05/13] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E4=BA=86?= =?UTF-8?q?=E4=BA=BA=E6=A0=BC=E8=AE=BE=E7=BD=AE=E4=BF=9D=E5=AD=98=E4=B8=8D?= =?UTF-8?q?=E4=BA=86=E7=9A=84bug(=E6=84=9F=E8=B0=A2=E5=A4=A7=E4=BD=ACZureT?= =?UTF-8?q?z=E6=8F=90=E4=BE=9B=E7=9A=84=E4=BF=AE=E5=A4=8D=EF=BC=81)?= =?UTF-8?q?=EF=BC=8C=E4=BF=AE=E5=A4=8D=E5=85=B6=E4=BB=96=E9=A1=B9=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E4=BF=9D=E5=AD=98=E4=B8=8D=E4=BA=86=E7=9A=84bug?= =?UTF-8?q?=EF=BC=8C=E4=BF=AE=E5=A4=8D=E9=83=A8=E5=88=86=E6=96=87=E5=AD=97?= =?UTF-8?q?=E8=A1=A8=E8=BF=B0=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- webui.py | 189 ++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 133 insertions(+), 56 deletions(-) diff --git a/webui.py b/webui.py index 717ddc1e..7a82f4f3 100644 --- a/webui.py +++ b/webui.py @@ -2,12 +2,13 @@ import gradio as gr import os import sys import toml -from loguru import logger +from src.common.logger import get_module_logger import shutil import ast import json from packaging import version +logger = get_module_logger("webui") is_share = False debug = True @@ -17,8 +18,8 @@ CONFIG_VERSION = config_data["inner"]["version"] PARSED_CONFIG_VERSION = version.parse(CONFIG_VERSION) HAVE_ONLINE_STATUS_VERSION = version.parse("0.0.9") -#============================================== -#env环境配置文件读取部分 +# ============================================== +# env环境配置文件读取部分 def parse_env_config(config_file): """ 解析配置文件并将配置项存储到相应的变量中(变量名以env_为前缀)。 @@ -52,7 +53,7 @@ def parse_env_config(config_file): return env_variables -#env环境配置文件保存函数 +# env环境配置文件保存函数 def save_to_env_file(env_variables, filename=".env.prod"): """ 将修改后的变量保存到指定的.env文件中,并在第一次保存前备份文件(如果备份文件不存在)。 @@ -75,7 +76,7 @@ def save_to_env_file(env_variables, filename=".env.prod"): logger.info(f"配置已保存到 {filename}") -#载入env文件并解析 +# 载入env文件并解析 env_config_file = ".env.prod" # 配置文件路径 env_config_data = parse_env_config(env_config_file) if "env_VOLCENGINE_BASE_URL" in env_config_data: @@ -97,8 +98,8 @@ MODEL_PROVIDER_LIST = [ "SILICONFLOW", "DEEP_SEEK" ] -#env读取保存结束 -#============================================== +# env读取保存结束 +# ============================================== #获取在线麦麦数量 import requests @@ -188,7 +189,7 @@ def delete_int_item(selected_item, current_list): gr.update(choices=updated_list), ", ".join(map(str, updated_list)) ] -#env文件中插件值处理函数 +# env文件中插件值处理函数 def parse_list_str(input_str): """ 将形如["src2.plugins.chat"]的字符串解析为Python列表 @@ -222,7 +223,7 @@ def format_list_to_str(lst): return "[" + res + "]" -#env保存函数 +# env保存函数 def save_trigger(server_address, server_port, final_result_list,t_mongodb_host,t_mongodb_port,t_mongodb_database_name,t_chatanywhere_base_url,t_chatanywhere_key,t_siliconflow_base_url,t_siliconflow_key,t_deepseek_base_url,t_deepseek_key,t_volcengine_base_url,t_volcengine_key): final_result_lists = format_list_to_str(final_result_list) env_config_data["env_HOST"] = server_address @@ -243,11 +244,11 @@ def save_trigger(server_address, server_port, final_result_list,t_mongodb_host,t logger.success("配置已保存到 .env.prod 文件中") return "配置已保存" -#============================================== +# ============================================== -#============================================== -#主要配置文件保存函数 +# ============================================== +# 主要配置文件保存函数 def save_config_to_file(t_config_data): filename = "config/bot_config.toml" backup_filename = f"{filename}.bak" @@ -272,49 +273,62 @@ def save_bot_config(t_qqbot_qq, t_nickname,t_nickname_final_result): return "Bot配置已保存" # 监听滑块的值变化,确保总和不超过 1,并显示警告 -def adjust_greater_probabilities(t_personality_1, t_personality_2, t_personality_3): - total = t_personality_1 + t_personality_2 + t_personality_3 +def adjust_personality_greater_probabilities(t_personality_1_probability, t_personality_2_probability, t_personality_3_probability): + total = t_personality_1_probability + t_personality_2_probability + t_personality_3_probability if total > 1.0: warning_message = f"警告: 人格1、人格2和人格3的概率总和为 {total:.2f},超过了 1.0!请调整滑块使总和等于 1.0。" return warning_message - else: - return "" # 没有警告时返回空字符串 + return "" # 没有警告时返回空字符串 -def adjust_less_probabilities(t_personality_1, t_personality_2, t_personality_3): - total = t_personality_1 + t_personality_2 + t_personality_3 +def adjust_personality_less_probabilities(t_personality_1_probability, t_personality_2_probability, t_personality_3_probability): + total = t_personality_1_probability + t_personality_2_probability + t_personality_3_probability if total < 1.0: warning_message = f"警告: 人格1、人格2和人格3的概率总和为 {total:.2f},小于 1.0!请调整滑块使总和等于 1.0。" return warning_message - else: - return "" # 没有警告时返回空字符串 + return "" # 没有警告时返回空字符串 -def adjust_model_greater_probabilities(t_personality_1, t_personality_2, t_personality_3): - total = t_personality_1 + t_personality_2 + t_personality_3 +def adjust_model_greater_probabilities(t_model_1_probability, t_model_2_probability, t_model_3_probability): + total = t_model_1_probability + t_model_2_probability + t_model_3_probability if total > 1.0: warning_message = f"警告: 选择模型1、模型2和模型3的概率总和为 {total:.2f},超过了 1.0!请调整滑块使总和等于 1.0。" return warning_message - else: - return "" # 没有警告时返回空字符串 + return "" # 没有警告时返回空字符串 -def adjust_model_less_probabilities(t_personality_1, t_personality_2, t_personality_3): - total = t_personality_1 + t_personality_2 + t_personality_3 +def adjust_model_less_probabilities(t_model_1_probability, t_model_2_probability, t_model_3_probability): + total = t_model_1_probability + t_model_2_probability + t_model_3_probability if total > 1.0: warning_message = f"警告: 选择模型1、模型2和模型3的概率总和为 {total:.2f},小于了 1.0!请调整滑块使总和等于 1.0。" return warning_message - else: - return "" # 没有警告时返回空字符串 + return "" # 没有警告时返回空字符串 -#============================================== -#人格保存函数 -def save_personality_config(t_personality_1, t_personality_2, t_personality_3, t_prompt_schedule): - config_data["personality"]["personality_1_probability"] = t_personality_1 - config_data["personality"]["personality_2_probability"] = t_personality_2 - config_data["personality"]["personality_3_probability"] = t_personality_3 + +# ============================================== +# 人格保存函数 +def save_personality_config(t_prompt_personality_1, + t_prompt_personality_2, + t_prompt_personality_3, + t_prompt_schedule, + t_personality_1_probability, + t_personality_2_probability, + t_personality_3_probability): + # 保存人格提示词 + config_data["personality"]["prompt_personality"][0] = t_prompt_personality_1 + config_data["personality"]["prompt_personality"][1] = t_prompt_personality_2 + config_data["personality"]["prompt_personality"][2] = t_prompt_personality_3 + + # 保存日程生成提示词 config_data["personality"]["prompt_schedule"] = t_prompt_schedule + + # 保存三个人格的概率 + config_data["personality"]["personality_1_probability"] = t_personality_1_probability + config_data["personality"]["personality_2_probability"] = t_personality_2_probability + config_data["personality"]["personality_3_probability"] = t_personality_3_probability + save_config_to_file(config_data) logger.info("人格配置已保存到 bot_config.toml 文件中") return "人格配置已保存" + def save_message_and_emoji_config(t_min_text_length, t_max_context_size, t_emoji_chance, @@ -415,7 +429,7 @@ def save_other_config(t_keywords_reaction_enabled,t_enable_advance_output, t_ena config_data["chinese_typo"]["min_freq"] = t_min_freq config_data["chinese_typo"]["tone_error_rate"] = t_tone_error_rate config_data["chinese_typo"]["word_replace_rate"] = t_word_replace_rate - if PARSED_CONFIG_VERSION > 0.8: + if PARSED_CONFIG_VERSION > HAVE_ONLINE_STATUS_VERSION: config_data["remote"]["enable"] = t_remote_status save_config_to_file(config_data) logger.info("其他设置已保存到 bot_config.toml 文件中") @@ -435,6 +449,7 @@ with gr.Blocks(title="MaimBot配置文件编辑") as app: gr.Markdown( value=""" ### 欢迎使用由墨梓柒MotricSeven编写的MaimBot配置文件编辑器\n + 感谢ZureTz大佬提供的人格保存部分修复! """ ) gr.Markdown( @@ -531,19 +546,19 @@ with gr.Blocks(title="MaimBot配置文件编辑") as app: ) with gr.Row(): gr.Markdown( - '''ChatAntWhere的baseURL和APIkey\n + '''ChatAnyWhere的baseURL和APIkey\n 改完了记得保存!!! ''' ) with gr.Row(): chatanywhere_base_url = gr.Textbox( - label="ChatAntWhere的BaseURL", + label="ChatAnyWhere的BaseURL", value=env_config_data["env_CHAT_ANY_WHERE_BASE_URL"], interactive=True ) with gr.Row(): chatanywhere_key = gr.Textbox( - label="ChatAntWhere的key", + label="ChatAnyWhere的key", value=env_config_data["env_CHAT_ANY_WHERE_KEY"], interactive=True ) @@ -676,38 +691,92 @@ with gr.Blocks(title="MaimBot配置文件编辑") as app: with gr.Row(): prompt_personality_1 = gr.Textbox( label="人格1提示词", - value=config_data['personality']['prompt_personality'][0], - interactive=True + value=config_data["personality"]["prompt_personality"][0], + interactive=True, ) with gr.Row(): prompt_personality_2 = gr.Textbox( label="人格2提示词", - value=config_data['personality']['prompt_personality'][1], - interactive=True + value=config_data["personality"]["prompt_personality"][1], + interactive=True, ) with gr.Row(): prompt_personality_3 = gr.Textbox( label="人格3提示词", - value=config_data['personality']['prompt_personality'][2], - interactive=True + value=config_data["personality"]["prompt_personality"][2], + interactive=True, ) with gr.Column(scale=3): - # 创建三个滑块 - personality_1 = gr.Slider(minimum=0, maximum=1, step=0.01, value=config_data["personality"]["personality_1_probability"], label="人格1概率") - personality_2 = gr.Slider(minimum=0, maximum=1, step=0.01, value=config_data["personality"]["personality_2_probability"], label="人格2概率") - personality_3 = gr.Slider(minimum=0, maximum=1, step=0.01, value=config_data["personality"]["personality_3_probability"], label="人格3概率") + # 创建三个滑块, 代表三个人格的概率 + personality_1_probability = gr.Slider( + minimum=0, + maximum=1, + step=0.01, + value=config_data["personality"]["personality_1_probability"], + label="人格1概率", + ) + personality_2_probability = gr.Slider( + minimum=0, + maximum=1, + step=0.01, + value=config_data["personality"]["personality_2_probability"], + label="人格2概率", + ) + personality_3_probability = gr.Slider( + minimum=0, + maximum=1, + step=0.01, + value=config_data["personality"]["personality_3_probability"], + label="人格3概率", + ) # 用于显示警告消息 warning_greater_text = gr.Markdown() warning_less_text = gr.Markdown() # 绑定滑块的值变化事件,确保总和必须等于 1.0 - personality_1.change(adjust_greater_probabilities, inputs=[personality_1, personality_2, personality_3], outputs=[warning_greater_text]) - personality_2.change(adjust_greater_probabilities, inputs=[personality_1, personality_2, personality_3], outputs=[warning_greater_text]) - personality_3.change(adjust_greater_probabilities, inputs=[personality_1, personality_2, personality_3], outputs=[warning_greater_text]) - personality_1.change(adjust_less_probabilities, inputs=[personality_1, personality_2, personality_3], outputs=[warning_less_text]) - personality_2.change(adjust_less_probabilities, inputs=[personality_1, personality_2, personality_3], outputs=[warning_less_text]) - personality_3.change(adjust_less_probabilities, inputs=[personality_1, personality_2, personality_3], outputs=[warning_less_text]) + + # 输入的 3 个概率 + personality_probability_change_inputs = [ + personality_1_probability, + personality_2_probability, + personality_3_probability, + ] + + # 绑定滑块的值变化事件,确保总和不大于 1.0 + personality_1_probability.change( + adjust_personality_greater_probabilities, + inputs=personality_probability_change_inputs, + outputs=[warning_greater_text], + ) + personality_2_probability.change( + adjust_personality_greater_probabilities, + inputs=personality_probability_change_inputs, + outputs=[warning_greater_text], + ) + personality_3_probability.change( + adjust_personality_greater_probabilities, + inputs=personality_probability_change_inputs, + outputs=[warning_greater_text], + ) + + # 绑定滑块的值变化事件,确保总和不小于 1.0 + personality_1_probability.change( + adjust_personality_less_probabilities, + inputs=personality_probability_change_inputs, + outputs=[warning_less_text], + ) + personality_2_probability.change( + adjust_personality_less_probabilities, + inputs=personality_probability_change_inputs, + outputs=[warning_less_text], + ) + personality_3_probability.change( + adjust_personality_less_probabilities, + inputs=personality_probability_change_inputs, + outputs=[warning_less_text], + ) + with gr.Row(): prompt_schedule = gr.Textbox( label="日程生成提示词", @@ -725,8 +794,16 @@ with gr.Blocks(title="MaimBot配置文件编辑") as app: personal_save_message = gr.Textbox(label="保存人格结果") personal_save_btn.click( save_personality_config, - inputs=[personality_1, personality_2, personality_3, prompt_schedule], - outputs=[personal_save_message] + inputs=[ + prompt_personality_1, + prompt_personality_2, + prompt_personality_3, + prompt_schedule, + personality_1_probability, + personality_2_probability, + personality_3_probability, + ], + outputs=[personal_save_message], ) with gr.TabItem("3-消息&表情包设置"): with gr.Row(): From 933ab824f682c4790679e2c66e0dfa1a11c0c0f9 Mon Sep 17 00:00:00 2001 From: DrSmoothl <1787882683@qq.com> Date: Tue, 18 Mar 2025 20:47:58 +0800 Subject: [PATCH 06/13] Update webui.py Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com> --- webui.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webui.py b/webui.py index 7a82f4f3..cb395798 100644 --- a/webui.py +++ b/webui.py @@ -453,7 +453,7 @@ with gr.Blocks(title="MaimBot配置文件编辑") as app: """ ) gr.Markdown( - value="## 全球在线MaiMBot数量: " + str(online_maimbot_data['online_clients']) + value="## 全球在线MaiMBot数量: " + str((online_maimbot_data or {}).get('online_clients', 0)) ) gr.Markdown( From a402f6b3d5fa0fbbdb0c25d560ff769fc05f015b Mon Sep 17 00:00:00 2001 From: Cookie987 Date: Tue, 18 Mar 2025 22:14:39 +0800 Subject: [PATCH 07/13] =?UTF-8?q?=E9=80=82=E9=85=8D=E6=9C=80=E6=96=B0?= =?UTF-8?q?=E7=9A=84=E5=8D=8F=E8=AE=AE=E6=A3=80=E6=9F=A5=E6=9C=BA=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- run_debian12.sh | 51 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 48 insertions(+), 3 deletions(-) diff --git a/run_debian12.sh b/run_debian12.sh index 5a51a1a3..6550a01b 100644 --- a/run_debian12.sh +++ b/run_debian12.sh @@ -186,6 +186,42 @@ update_config() { fi } +check_eula() { + # 首先计算当前EULA的MD5值 + current_md5=$(md5sum ${INSTALL_DIR}/repo/EULA.md | awk '{print $1}') + + # 首先计算当前隐私条款文件的哈希值 + current_md5_privacy=$(md5sum ${INSTALL_DIR}/repo/PRIVACY.md | awk '{print $1}') + + # 检查eula.confirmed文件是否存在 + if [[ -f repo/elua.confirmed ]]; then + # 如果存在则检查其中包含的md5与current_md5是否一致 + confirmed_md5=$(cat ${INSTALL_DIR}/repo/elua.confirmed) + else + confirmed_md5="" + fi + + # 检查privacy.confirmed文件是否存在 + if [[ -f repo/privacy ]]; then + # 如果存在则检查其中包含的md5与current_md5是否一致 + confirmed_md5_privacy=$(cat ${INSTALL_DIR}/repo/privacy.confirmed) + else + confirmed_md5_privacy="" + fi + + # 如果EULA或隐私条款有更新,提示用户重新确认 + if [[ $current_md5 != $confirmed_md5 || $current_md5_privacy != $confirmed_md5_privacy ]]; then + whiptail --title "📜 使用协议更新" --yesno "检测到麦麦Bot EULA或隐私条款已更新。\nhttps://github.com/SengokuCola/MaiMBot/blob/main/EULA.md\nhttps://github.com/SengokuCola/MaiMBot/blob/main/PRIVACY.md\n\n您是否同意上述协议? \n\n " 12 70 + if [[ $? -eq 0 ]]; then + echo $current_md5 > ${INSTALL_DIR}/repo/elua.confirmed + echo $current_md5_privacy > ${INSTALL_DIR}/repo/privacy.confirmed + else + exit 1 + fi + fi + +} + # ----------- 主安装流程 ----------- run_installation() { # 1/6: 检测是否安装 whiptail @@ -195,7 +231,7 @@ run_installation() { fi # 协议确认 - if ! (whiptail --title "ℹ️ [1/6] 使用协议" --yes-button "我同意" --no-button "我拒绝" --yesno "使用麦麦Bot及此脚本前请先阅读ELUA协议\nhttps://github.com/SengokuCola/MaiMBot/blob/main/EULA.md\n\n您是否同意此协议?" 12 70); then + if ! (whiptail --title "ℹ️ [1/6] 使用协议" --yes-button "我同意" --no-button "我拒绝" --yesno "使用麦麦Bot及此脚本前请先阅读ELUA协议及隐私协议\nhttps://github.com/SengokuCola/MaiMBot/blob/main/EULA.md\nhttps://github.com/SengokuCola/MaiMBot/blob/main/PRIVACY.md\n\n您是否同意上述协议?" 12 70); then exit 1 fi @@ -355,7 +391,15 @@ run_installation() { pip install -r repo/requirements.txt echo -e "${GREEN}同意协议...${RESET}" - touch repo/elua.confirmed + + # 首先计算当前EULA的MD5值 + current_md5=$(md5sum repo/EULA.md | awk '{print $1}') + + # 首先计算当前隐私条款文件的哈希值 + current_md5_privacy=$(md5sum repo/PRIVACY.md | awk '{print $1}') + + echo $current_md5 > repo/elua.confirmed + echo $current_md5_privacy > repo/privacy.confirmed echo -e "${GREEN}创建系统服务...${RESET}" cat > /etc/systemd/system/${SERVICE_NAME}.service < Date: Tue, 18 Mar 2025 22:17:14 +0800 Subject: [PATCH 08/13] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=BC=8F=E6=8E=89?= =?UTF-8?q?=E7=9A=84=E8=B7=AF=E5=BE=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- run_debian12.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/run_debian12.sh b/run_debian12.sh index 6550a01b..f352bca9 100644 --- a/run_debian12.sh +++ b/run_debian12.sh @@ -194,7 +194,7 @@ check_eula() { current_md5_privacy=$(md5sum ${INSTALL_DIR}/repo/PRIVACY.md | awk '{print $1}') # 检查eula.confirmed文件是否存在 - if [[ -f repo/elua.confirmed ]]; then + if [[ -f ${INSTALL_DIR}/repo/elua.confirmed ]]; then # 如果存在则检查其中包含的md5与current_md5是否一致 confirmed_md5=$(cat ${INSTALL_DIR}/repo/elua.confirmed) else @@ -202,7 +202,7 @@ check_eula() { fi # 检查privacy.confirmed文件是否存在 - if [[ -f repo/privacy ]]; then + if [[ -f ${INSTALL_DIR}/repo/privacy.confirmed ]]; then # 如果存在则检查其中包含的md5与current_md5是否一致 confirmed_md5_privacy=$(cat ${INSTALL_DIR}/repo/privacy.confirmed) else From 8c89c0b95e63d3c243521de550e353551e194ba6 Mon Sep 17 00:00:00 2001 From: Cookie987 Date: Tue, 18 Mar 2025 22:22:48 +0800 Subject: [PATCH 09/13] =?UTF-8?q?=E9=9A=BE=E7=BB=B7=E7=9A=84typo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- run_debian12.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/run_debian12.sh b/run_debian12.sh index f352bca9..7acd62e5 100644 --- a/run_debian12.sh +++ b/run_debian12.sh @@ -161,8 +161,8 @@ switch_branch() { sed -i "s/^BRANCH=.*/BRANCH=${new_branch}/" /etc/maimbot_install.conf BRANCH="${new_branch}" + check_eula systemctl restart ${SERVICE_NAME} - touch "${INSTALL_DIR}/repo/elua.confirmed" whiptail --msgbox "✅ 已切换到分支 ${new_branch} 并重启服务!" 10 60 } @@ -194,9 +194,9 @@ check_eula() { current_md5_privacy=$(md5sum ${INSTALL_DIR}/repo/PRIVACY.md | awk '{print $1}') # 检查eula.confirmed文件是否存在 - if [[ -f ${INSTALL_DIR}/repo/elua.confirmed ]]; then + if [[ -f ${INSTALL_DIR}/repo/eula.confirmed ]]; then # 如果存在则检查其中包含的md5与current_md5是否一致 - confirmed_md5=$(cat ${INSTALL_DIR}/repo/elua.confirmed) + confirmed_md5=$(cat ${INSTALL_DIR}/repo/eula.confirmed) else confirmed_md5="" fi @@ -213,7 +213,7 @@ check_eula() { if [[ $current_md5 != $confirmed_md5 || $current_md5_privacy != $confirmed_md5_privacy ]]; then whiptail --title "📜 使用协议更新" --yesno "检测到麦麦Bot EULA或隐私条款已更新。\nhttps://github.com/SengokuCola/MaiMBot/blob/main/EULA.md\nhttps://github.com/SengokuCola/MaiMBot/blob/main/PRIVACY.md\n\n您是否同意上述协议? \n\n " 12 70 if [[ $? -eq 0 ]]; then - echo $current_md5 > ${INSTALL_DIR}/repo/elua.confirmed + echo $current_md5 > ${INSTALL_DIR}/repo/eula.confirmed echo $current_md5_privacy > ${INSTALL_DIR}/repo/privacy.confirmed else exit 1 @@ -231,7 +231,7 @@ run_installation() { fi # 协议确认 - if ! (whiptail --title "ℹ️ [1/6] 使用协议" --yes-button "我同意" --no-button "我拒绝" --yesno "使用麦麦Bot及此脚本前请先阅读ELUA协议及隐私协议\nhttps://github.com/SengokuCola/MaiMBot/blob/main/EULA.md\nhttps://github.com/SengokuCola/MaiMBot/blob/main/PRIVACY.md\n\n您是否同意上述协议?" 12 70); then + if ! (whiptail --title "ℹ️ [1/6] 使用协议" --yes-button "我同意" --no-button "我拒绝" --yesno "使用麦麦Bot及此脚本前请先阅读EULA协议及隐私协议\nhttps://github.com/SengokuCola/MaiMBot/blob/main/EULA.md\nhttps://github.com/SengokuCola/MaiMBot/blob/main/PRIVACY.md\n\n您是否同意上述协议?" 12 70); then exit 1 fi @@ -398,7 +398,7 @@ run_installation() { # 首先计算当前隐私条款文件的哈希值 current_md5_privacy=$(md5sum repo/PRIVACY.md | awk '{print $1}') - echo $current_md5 > repo/elua.confirmed + echo $current_md5 > repo/eula.confirmed echo $current_md5_privacy > repo/privacy.confirmed echo -e "${GREEN}创建系统服务...${RESET}" From 8dfccfce76599eb5a9aa6acc70c4805da452f6f5 Mon Sep 17 00:00:00 2001 From: Cookie987 Date: Tue, 18 Mar 2025 22:28:03 +0800 Subject: [PATCH 10/13] =?UTF-8?q?=E5=8F=82=E6=95=B0=E5=8A=A0=E5=BC=95?= =?UTF-8?q?=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- run_debian12.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/run_debian12.sh b/run_debian12.sh index 7acd62e5..ae189844 100644 --- a/run_debian12.sh +++ b/run_debian12.sh @@ -188,10 +188,10 @@ update_config() { check_eula() { # 首先计算当前EULA的MD5值 - current_md5=$(md5sum ${INSTALL_DIR}/repo/EULA.md | awk '{print $1}') + current_md5=$(md5sum "${INSTALL_DIR}/repo/EULA.md" | awk '{print $1}') # 首先计算当前隐私条款文件的哈希值 - current_md5_privacy=$(md5sum ${INSTALL_DIR}/repo/PRIVACY.md | awk '{print $1}') + current_md5_privacy=$(md5sum "${INSTALL_DIR}/repo/PRIVACY.md" | awk '{print $1}') # 检查eula.confirmed文件是否存在 if [[ -f ${INSTALL_DIR}/repo/eula.confirmed ]]; then @@ -393,10 +393,10 @@ run_installation() { echo -e "${GREEN}同意协议...${RESET}" # 首先计算当前EULA的MD5值 - current_md5=$(md5sum repo/EULA.md | awk '{print $1}') + current_md5=$(md5sum "repo/EULA.md" | awk '{print $1}') # 首先计算当前隐私条款文件的哈希值 - current_md5_privacy=$(md5sum repo/PRIVACY.md | awk '{print $1}') + current_md5_privacy=$(md5sum "repo/PRIVACY.md" | awk '{print $1}') echo $current_md5 > repo/eula.confirmed echo $current_md5_privacy > repo/privacy.confirmed From 4d1e5395d6ec3e17a4446217c933bc1c16176136 Mon Sep 17 00:00:00 2001 From: DrSmoothl <1787882683@qq.com> Date: Tue, 18 Mar 2025 23:17:16 +0800 Subject: [PATCH 11/13] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E4=BA=86?= =?UTF-8?q?=E8=87=AA=E5=AE=9A=E4=B9=89API=E6=8F=90=E4=BE=9B=E5=95=86?= =?UTF-8?q?=E6=97=A0=E6=B3=95=E8=AF=86=E5=88=AB=E7=9A=84=E9=97=AE=E9=A2=98?= =?UTF-8?q?=E3=80=82=E5=A2=9E=E5=8A=A0=E6=96=B0=E7=9A=84env=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E9=85=8D=E7=BD=AE=E9=A1=B9=EF=BC=8C=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=EF=BC=9A=E5=8F=AF=E4=BB=A5=E8=87=AA=E5=B7=B1?= =?UTF-8?q?=E5=9C=A8WebUI=E4=B8=AD=E6=B7=BB=E5=8A=A0=E6=8F=90=E4=BE=9B?= =?UTF-8?q?=E5=95=86=E3=80=82=E5=A2=9E=E5=8A=A0=E6=A3=80=E6=B5=8B=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E6=98=AF=E5=90=A6=E5=AD=98=E5=9C=A8=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- webui.py | 205 ++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 144 insertions(+), 61 deletions(-) diff --git a/webui.py b/webui.py index 7a82f4f3..1155e4db 100644 --- a/webui.py +++ b/webui.py @@ -1,6 +1,5 @@ import gradio as gr import os -import sys import toml from src.common.logger import get_module_logger import shutil @@ -12,12 +11,24 @@ logger = get_module_logger("webui") is_share = False debug = True +# 检查配置文件是否存在 +if not os.path.exists("config/bot_config.toml"): + logger.error("配置文件 bot_config.toml 不存在,请检查配置文件路径") + raise FileNotFoundError("配置文件 bot_config.toml 不存在,请检查配置文件路径") + +if not os.path.exists(".env.prod"): + logger.error("环境配置文件 .env.prod 不存在,请检查配置文件路径") + raise FileNotFoundError("环境配置文件 .env.prod 不存在,请检查配置文件路径") + config_data = toml.load("config/bot_config.toml") CONFIG_VERSION = config_data["inner"]["version"] PARSED_CONFIG_VERSION = version.parse(CONFIG_VERSION) HAVE_ONLINE_STATUS_VERSION = version.parse("0.0.9") +#添加WebUI配置文件版本 +WEBUI_VERSION = version.parse("0.0.7") + # ============================================== # env环境配置文件读取部分 def parse_env_config(config_file): @@ -92,12 +103,50 @@ else: logger.info("VOLCENGINE_KEY 不存在,已创建并使用默认值") env_config_data["env_VOLCENGINE_KEY"] = "volc_key" save_to_env_file(env_config_data, env_config_file) -MODEL_PROVIDER_LIST = [ - "VOLCENGINE", - "CHAT_ANY_WHERE", - "SILICONFLOW", - "DEEP_SEEK" -] + +def parse_model_providers(env_vars): + """ + 从环境变量中解析模型提供商列表 + 参数: + env_vars: 包含环境变量的字典 + 返回: + list: 模型提供商列表 + """ + providers = [] + for key in env_vars.keys(): + if key.startswith("env_") and key.endswith("_BASE_URL"): + # 提取中间部分作为提供商名称 + provider = key[4:-9] # 移除"env_"前缀和"_BASE_URL"后缀 + providers.append(provider) + return providers + +def add_new_provider(provider_name, current_providers): + """ + 添加新的提供商到列表中 + 参数: + provider_name: 新的提供商名称 + current_providers: 当前的提供商列表 + 返回: + tuple: (更新后的提供商列表, 更新后的下拉列表选项) + """ + if not provider_name or provider_name in current_providers: + return current_providers, gr.update(choices=current_providers) + + # 添加新的提供商到环境变量中 + env_config_data[f"env_{provider_name}_BASE_URL"] = "" + env_config_data[f"env_{provider_name}_KEY"] = "" + + # 更新提供商列表 + updated_providers = current_providers + [provider_name] + + # 保存到环境文件 + save_to_env_file(env_config_data) + + return updated_providers, gr.update(choices=updated_providers) + +# 从环境变量中解析并更新提供商列表 +MODEL_PROVIDER_LIST = parse_model_providers(env_config_data) + # env读取保存结束 # ============================================== @@ -224,7 +273,7 @@ def format_list_to_str(lst): # env保存函数 -def save_trigger(server_address, server_port, final_result_list,t_mongodb_host,t_mongodb_port,t_mongodb_database_name,t_chatanywhere_base_url,t_chatanywhere_key,t_siliconflow_base_url,t_siliconflow_key,t_deepseek_base_url,t_deepseek_key,t_volcengine_base_url,t_volcengine_key): +def save_trigger(server_address, server_port, final_result_list, t_mongodb_host, t_mongodb_port, t_mongodb_database_name, t_console_log_level, t_file_log_level, t_default_console_log_level, t_default_file_log_level, t_api_provider, t_api_base_url, t_api_key): final_result_lists = format_list_to_str(final_result_list) env_config_data["env_HOST"] = server_address env_config_data["env_PORT"] = server_port @@ -232,18 +281,32 @@ def save_trigger(server_address, server_port, final_result_list,t_mongodb_host,t env_config_data["env_MONGODB_HOST"] = t_mongodb_host env_config_data["env_MONGODB_PORT"] = t_mongodb_port env_config_data["env_DATABASE_NAME"] = t_mongodb_database_name - env_config_data["env_CHAT_ANY_WHERE_BASE_URL"] = t_chatanywhere_base_url - env_config_data["env_CHAT_ANY_WHERE_KEY"] = t_chatanywhere_key - env_config_data["env_SILICONFLOW_BASE_URL"] = t_siliconflow_base_url - env_config_data["env_SILICONFLOW_KEY"] = t_siliconflow_key - env_config_data["env_DEEP_SEEK_BASE_URL"] = t_deepseek_base_url - env_config_data["env_DEEP_SEEK_KEY"] = t_deepseek_key - env_config_data["env_VOLCENGINE_BASE_URL"] = t_volcengine_base_url - env_config_data["env_VOLCENGINE_KEY"] = t_volcengine_key + + # 保存日志配置 + env_config_data["env_CONSOLE_LOG_LEVEL"] = t_console_log_level + env_config_data["env_FILE_LOG_LEVEL"] = t_file_log_level + env_config_data["env_DEFAULT_CONSOLE_LOG_LEVEL"] = t_default_console_log_level + env_config_data["env_DEFAULT_FILE_LOG_LEVEL"] = t_default_file_log_level + + # 保存选中的API提供商的配置 + env_config_data[f"env_{t_api_provider}_BASE_URL"] = t_api_base_url + env_config_data[f"env_{t_api_provider}_KEY"] = t_api_key + save_to_env_file(env_config_data) logger.success("配置已保存到 .env.prod 文件中") return "配置已保存" +def update_api_inputs(provider): + """ + 根据选择的提供商更新Base URL和API Key输入框的值 + """ + base_url = env_config_data.get(f"env_{provider}_BASE_URL", "") + api_key = env_config_data.get(f"env_{provider}_KEY", "") + return base_url, api_key + +# 绑定下拉列表的change事件 + + # ============================================== @@ -455,7 +518,9 @@ with gr.Blocks(title="MaimBot配置文件编辑") as app: gr.Markdown( value="## 全球在线MaiMBot数量: " + str(online_maimbot_data['online_clients']) ) - + gr.Markdown( + value="## 当前WebUI版本: " + str(WEBUI_VERSION) + ) gr.Markdown( value="### 配置文件版本:" + config_data["inner"]["version"] ) @@ -546,81 +611,99 @@ with gr.Blocks(title="MaimBot配置文件编辑") as app: ) with gr.Row(): gr.Markdown( - '''ChatAnyWhere的baseURL和APIkey\n + '''日志设置\n + 配置日志输出级别\n 改完了记得保存!!! ''' ) with gr.Row(): - chatanywhere_base_url = gr.Textbox( - label="ChatAnyWhere的BaseURL", - value=env_config_data["env_CHAT_ANY_WHERE_BASE_URL"], + console_log_level = gr.Dropdown( + choices=["INFO", "DEBUG", "WARNING", "ERROR", "SUCCESS"], + label="控制台日志级别", + value=env_config_data.get("env_CONSOLE_LOG_LEVEL", "INFO"), interactive=True ) with gr.Row(): - chatanywhere_key = gr.Textbox( - label="ChatAnyWhere的key", - value=env_config_data["env_CHAT_ANY_WHERE_KEY"], + file_log_level = gr.Dropdown( + choices=["INFO", "DEBUG", "WARNING", "ERROR", "SUCCESS"], + label="文件日志级别", + value=env_config_data.get("env_FILE_LOG_LEVEL", "DEBUG"), + interactive=True + ) + with gr.Row(): + default_console_log_level = gr.Dropdown( + choices=["INFO", "DEBUG", "WARNING", "ERROR", "SUCCESS", "NONE"], + label="默认控制台日志级别", + value=env_config_data.get("env_DEFAULT_CONSOLE_LOG_LEVEL", "SUCCESS"), + interactive=True + ) + with gr.Row(): + default_file_log_level = gr.Dropdown( + choices=["INFO", "DEBUG", "WARNING", "ERROR", "SUCCESS", "NONE"], + label="默认文件日志级别", + value=env_config_data.get("env_DEFAULT_FILE_LOG_LEVEL", "DEBUG"), interactive=True ) with gr.Row(): gr.Markdown( - '''SiliconFlow的baseURL和APIkey\n + '''API设置\n + 选择API提供商并配置相应的BaseURL和Key\n 改完了记得保存!!! ''' ) with gr.Row(): - siliconflow_base_url = gr.Textbox( - label="SiliconFlow的BaseURL", - value=env_config_data["env_SILICONFLOW_BASE_URL"], + with gr.Column(scale=3): + new_provider_input = gr.Textbox( + label="添加新提供商", + placeholder="输入新提供商名称" + ) + add_provider_btn = gr.Button("添加提供商", scale=1) + with gr.Row(): + api_provider = gr.Dropdown( + choices=MODEL_PROVIDER_LIST, + label="选择API提供商", + value=MODEL_PROVIDER_LIST[0] if MODEL_PROVIDER_LIST else None + ) + + with gr.Row(): + api_base_url = gr.Textbox( + label="Base URL", + value=env_config_data.get(f"env_{MODEL_PROVIDER_LIST[0]}_BASE_URL", "") if MODEL_PROVIDER_LIST else "", interactive=True ) with gr.Row(): - siliconflow_key = gr.Textbox( - label="SiliconFlow的key", - value=env_config_data["env_SILICONFLOW_KEY"], + api_key = gr.Textbox( + label="API Key", + value=env_config_data.get(f"env_{MODEL_PROVIDER_LIST[0]}_KEY", "") if MODEL_PROVIDER_LIST else "", interactive=True ) - with gr.Row(): - gr.Markdown( - '''DeepSeek的baseURL和APIkey\n - 改完了记得保存!!! - ''' - ) - with gr.Row(): - deepseek_base_url = gr.Textbox( - label="DeepSeek的BaseURL", - value=env_config_data["env_DEEP_SEEK_BASE_URL"], - interactive=True - ) - with gr.Row(): - deepseek_key = gr.Textbox( - label="DeepSeek的key", - value=env_config_data["env_DEEP_SEEK_KEY"], - interactive=True - ) - with gr.Row(): - volcengine_base_url = gr.Textbox( - label="VolcEngine的BaseURL", - value=env_config_data["env_VOLCENGINE_BASE_URL"], - interactive=True - ) - with gr.Row(): - volcengine_key = gr.Textbox( - label="VolcEngine的key", - value=env_config_data["env_VOLCENGINE_KEY"], - interactive=True + api_provider.change( + update_api_inputs, + inputs=[api_provider], + outputs=[api_base_url, api_key] ) with gr.Row(): save_env_btn = gr.Button("保存环境配置",variant="primary") with gr.Row(): save_env_btn.click( save_trigger, - inputs=[server_address,server_port,final_result,mongodb_host,mongodb_port,mongodb_database_name,chatanywhere_base_url,chatanywhere_key,siliconflow_base_url,siliconflow_key,deepseek_base_url,deepseek_key,volcengine_base_url,volcengine_key], + inputs=[server_address, server_port, final_result, mongodb_host, mongodb_port, mongodb_database_name, console_log_level, file_log_level, default_console_log_level, default_file_log_level, api_provider, api_base_url, api_key], outputs=[gr.Textbox( label="保存结果", interactive=False )] ) + + # 绑定添加提供商按钮的点击事件 + add_provider_btn.click( + add_new_provider, + inputs=[new_provider_input, gr.State(value=MODEL_PROVIDER_LIST)], + outputs=[gr.State(value=MODEL_PROVIDER_LIST), api_provider] + ).then( + lambda x: (env_config_data.get(f"env_{x}_BASE_URL", ""), env_config_data.get(f"env_{x}_KEY", "")), + inputs=[api_provider], + outputs=[api_base_url, api_key] + ) with gr.TabItem("1-Bot基础设置"): with gr.Row(): with gr.Column(scale=3): From 058b49e589df94fa5d0ac7edc6306f94c623c691 Mon Sep 17 00:00:00 2001 From: DrSmoothl <1787882683@qq.com> Date: Tue, 18 Mar 2025 23:40:31 +0800 Subject: [PATCH 12/13] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E4=BA=86?= =?UTF-8?q?=E4=B8=80=E4=BA=9B=E4=BB=A4=E4=BA=BA=E9=9A=BE=E8=9A=8C=E7=9A=84?= =?UTF-8?q?bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- webui.py | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/webui.py b/webui.py index 65efe06e..fe6c9d99 100644 --- a/webui.py +++ b/webui.py @@ -6,6 +6,7 @@ import shutil import ast import json from packaging import version +from decimal import Decimal, ROUND_DOWN logger = get_module_logger("webui") @@ -337,30 +338,30 @@ def save_bot_config(t_qqbot_qq, t_nickname,t_nickname_final_result): # 监听滑块的值变化,确保总和不超过 1,并显示警告 def adjust_personality_greater_probabilities(t_personality_1_probability, t_personality_2_probability, t_personality_3_probability): - total = t_personality_1_probability + t_personality_2_probability + t_personality_3_probability - if total > 1.0: - warning_message = f"警告: 人格1、人格2和人格3的概率总和为 {total:.2f},超过了 1.0!请调整滑块使总和等于 1.0。" + total = Decimal(str(t_personality_1_probability)) + Decimal(str(t_personality_2_probability)) + Decimal(str(t_personality_3_probability)) + if total > Decimal('1.0'): + warning_message = f"警告: 人格1、人格2和人格3的概率总和为 {float(total):.2f},超过了 1.0!请调整滑块使总和等于 1.0。" return warning_message return "" # 没有警告时返回空字符串 def adjust_personality_less_probabilities(t_personality_1_probability, t_personality_2_probability, t_personality_3_probability): - total = t_personality_1_probability + t_personality_2_probability + t_personality_3_probability - if total < 1.0: - warning_message = f"警告: 人格1、人格2和人格3的概率总和为 {total:.2f},小于 1.0!请调整滑块使总和等于 1.0。" + total = Decimal(str(t_personality_1_probability)) + Decimal(str(t_personality_2_probability)) + Decimal(str(t_personality_3_probability)) + if total < Decimal('1.0'): + warning_message = f"警告: 人格1、人格2和人格3的概率总和为 {float(total):.2f},小于 1.0!请调整滑块使总和等于 1.0。" return warning_message return "" # 没有警告时返回空字符串 def adjust_model_greater_probabilities(t_model_1_probability, t_model_2_probability, t_model_3_probability): - total = t_model_1_probability + t_model_2_probability + t_model_3_probability - if total > 1.0: - warning_message = f"警告: 选择模型1、模型2和模型3的概率总和为 {total:.2f},超过了 1.0!请调整滑块使总和等于 1.0。" + total = Decimal(str(t_model_1_probability)) + Decimal(str(t_model_2_probability)) + Decimal(str(t_model_3_probability)) + if total > Decimal('1.0'): + warning_message = f"警告: 选择模型1、模型2和模型3的概率总和为 {float(total):.2f},超过了 1.0!请调整滑块使总和等于 1.0。" return warning_message return "" # 没有警告时返回空字符串 def adjust_model_less_probabilities(t_model_1_probability, t_model_2_probability, t_model_3_probability): - total = t_model_1_probability + t_model_2_probability + t_model_3_probability - if total > 1.0: - warning_message = f"警告: 选择模型1、模型2和模型3的概率总和为 {total:.2f},小于了 1.0!请调整滑块使总和等于 1.0。" + total = Decimal(str(t_model_1_probability)) + Decimal(str(t_model_2_probability)) + Decimal(str(t_model_3_probability)) + if total < Decimal('1.0'): + warning_message = f"警告: 选择模型1、模型2和模型3的概率总和为 {float(total):.2f},小于了 1.0!请调整滑块使总和等于 1.0。" return warning_message return "" # 没有警告时返回空字符串 @@ -929,7 +930,7 @@ with gr.Blocks(title="MaimBot配置文件编辑") as app: choices=ban_words_list, label="选择要删除的违禁词" ) - ban_words_delete_btn = gr.Button("删除", scale=1) + ban_words_delete_btn = gr.Button("删除", scale=1) ban_words_final_result = gr.Text(label="修改后的违禁词") ban_words_add_btn.click( From 27e82389807a3cd67e55b7a15da1e31a7aaa532a Mon Sep 17 00:00:00 2001 From: DrSmoothl <1787882683@qq.com> Date: Tue, 18 Mar 2025 23:41:28 +0800 Subject: [PATCH 13/13] =?UTF-8?q?=E5=BF=98=E8=AE=B0=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E7=89=88=E6=9C=AC=E4=BA=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- webui.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webui.py b/webui.py index fe6c9d99..2c176082 100644 --- a/webui.py +++ b/webui.py @@ -28,7 +28,7 @@ PARSED_CONFIG_VERSION = version.parse(CONFIG_VERSION) HAVE_ONLINE_STATUS_VERSION = version.parse("0.0.9") #添加WebUI配置文件版本 -WEBUI_VERSION = version.parse("0.0.7") +WEBUI_VERSION = version.parse("0.0.8") # ============================================== # env环境配置文件读取部分