diff --git a/MaiLauncher.bat b/MaiLauncher.bat index 7b876bd37..766bfbfb5 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 设置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 +@echo off +@setlocal enabledelayedexpansion +@chcp 936 + +@REM 璁剧疆鐗堟湰鍙 +set "VERSION=1.0" + +title 楹﹂害Bot鎺у埗鍙 v%VERSION% + +@REM 璁剧疆Python鍜孏it鐜鍙橀噺 +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 姝e湪鑷姩鏌ユ壘Python瑙i噴鍣... + + 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噴鍣細%%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瑙i噴鍣,瑕佸畨瑁呭悧? + set /p pyinstall_confirm="缁х画锛(Y/n): " + if /i "!pyinstall_confirm!"=="Y" ( + cls + echo 姝e湪瀹夎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 瀹夎瀹屾垚锛屾鍦ㄩ獙璇丳ython... + goto search_python + + ) else ( + echo 鍙栨秷瀹夎Python锛屾寜浠绘剰閿鍑... + pause >nul + exit /b + ) + + echo 閿欒锛氭湭鎵惧埌鍙敤鐨凱ython瑙i噴鍣紒 + exit /b 1 + + :validate_python + "!py_path!" --version >nul 2>&1 + if %errorlevel% neq 0 ( + echo 鏃犳晥鐨凱ython瑙i噴鍣細%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 璇锋鏌ython瀹夎璺緞涓槸鍚︽湁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 姝e湪鑷姩鏌ユ壘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 姝e湪鎵弿甯歌瀹夎璺緞... + 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 姝e湪瀹夎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 姝e湪涓嬭浇Git瀹夎鍖... + curl -L -o "!download_path!" "!custom_url!" + + if exist "!download_path!" ( + echo 涓嬭浇鎴愬姛锛屽紑濮嬪畨瑁匞it... + start /wait "" "!download_path!" /SILENT /NORESTART + ) else ( + echo 涓嬭浇澶辫触锛岃鎵嬪姩瀹夎Git + start https://git-scm.com/download/win + exit /b + ) + + del "!download_path!" + echo 涓存椂鏂囦欢宸叉竻鐞嗐 + + echo 瀹夎瀹屾垚锛屾鍦ㄩ獙璇丟it... + 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 瀹夎瀹屾垚锛屼絾鏈壘鍒癎it锛岃鎵嬪姩瀹夎Git + start https://git-scm.com/download/win + exit /b + ) + + ) else ( + echo 鍙栨秷瀹夎Git锛屾寜浠绘剰閿鍑... + pause >nul + exit /b + ) + + echo 閿欒锛氭湭鎵惧埌鍙敤鐨凣it锛 + exit /b 1 + + :validate_git + "%git_path%" --version >nul 2>&1 + if %errorlevel% neq 0 ( + echo 鏃犳晥鐨凣it锛%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 姝e湪灏濊瘯鍚姩MongoDB鏈嶅姟... + powershell -Command "Start-Process -Verb RunAs cmd -ArgumentList '/c net start MongoDB'" + echo 姝e湪绛夊緟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 姝e湪瀹夎MongoDB... + winget install --id MongoDB.Server -e --accept-package-agreements --accept-source-agreements + echo 瀹夎瀹屾垚锛屾鍦ㄥ惎鍔∕ongoDB鏈嶅姟... + net start MongoDB + if !errorlevel! neq 0 ( + echo 鍚姩MongoDB鏈嶅姟澶辫触锛岃鎵嬪姩鍚姩 + exit /b + ) else ( + echo MongoDB鏈嶅姟宸叉垚鍔熷惎鍔 + ) + ) else ( + echo 鍙栨秷瀹夎MongoDB锛屾寜浠绘剰閿鍑... + pause >nul + exit /b + ) + ) + ) else ( + echo "璀﹀憡锛歁ongoDB鏈嶅姟鏈繍琛岋紝灏嗗鑷碝aiMBot鏃犳硶璁块棶鏁版嵁搴擄紒" + ) +) 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 浣犱技涔庢病鏈夊畨瑁呴害楹ot锛岃瀹夎鍦ㄥ綋鍓嶇洰褰曞悧锛 + set /p confirm="缁х画锛(Y/N): " + if /i "!confirm!"=="Y" ( + echo 瑕佷娇鐢℅it浠g悊涓嬭浇鍚楋紵 + set /p proxy_confirm="缁х画锛(Y/N): " + if /i "!proxy_confirm!"=="Y" ( + echo 姝e湪瀹夎楹﹂害Bot... + git clone https://ghfast.top/https://github.com/SengokuCola/MaiMBot + ) else ( + echo 姝e湪瀹夎楹﹂害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 姝e湪妫鏌ヨ櫄鎷熺幆澧冪姸鎬... +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 - 鍒涘缓骞舵縺娲籚env铏氭嫙鐜 +echo 2 - 鍒涘缓/婵娲籆onda铏氭嫙鐜 +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 宸插垱寤簄o_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 姝e湪鍒濆鍖朧env鐜... +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 宸叉縺娲籚env鐜 +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. 鏈畨瑁匨iniconda + 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 鎴愬姛婵娲籧onda鐜锛!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. 鏇存柊骞跺惎鍔ㄩ害楹ot (榛樿) +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 姝e湪鏇存柊渚濊禆... +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 姝e湪鍒囨崲鍒嗘敮... +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 姝e湪鍒囨崲鍒板垎鏀 %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 姝e湪閲嶇疆褰撳墠鍒嗘敮... +echo 褰撳墠鍒嗘敮: !BRANCH! +echo 纭瑕侀噸缃綋鍓嶅垎鏀悧锛 +set /p confirm="缁х画锛(Y/N): " +if /i "!confirm!"=="Y" ( + echo 姝e湪閲嶇疆褰撳墠鍒嗘敮... + git reset --hard !BRANCH! + echo 鍒嗘敮閲嶇疆瀹屾垚锛屾寜浠绘剰閿繑鍥炲伐鍏风鑿滃崟... +) else ( + echo 鍙栨秷閲嶇疆褰撳墠鍒嗘敮锛屾寜浠绘剰閿繑鍥炲伐鍏风鑿滃崟... +) +pause >nul +goto tools_menu + + +:update_config +cls +echo 姝e湪鏇存柊閰嶇疆鏂囦欢... +echo 璇风‘淇濆凡澶囦唤閲嶈鏁版嵁锛岀户缁皢淇敼褰撳墠閰嶇疆鏂囦欢銆 +echo 缁х画璇锋寜Y锛屽彇娑堣鎸変换鎰忛敭... +set /p confirm="缁х画锛(Y/N): " +if /i "!confirm!"=="Y" ( + echo 姝e湪鏇存柊閰嶇疆鏂囦欢... + python.exe config\auto_update.py + echo 閰嶇疆鏂囦欢鏇存柊瀹屾垚锛屾寜浠绘剰閿繑鍥炲伐鍏风鑿滃崟... +) else ( + echo 鍙栨秷鏇存柊閰嶇疆鏂囦欢锛屾寜浠绘剰閿繑鍥炲伐鍏风鑿滃崟... +) +pause >nul +goto tools_menu + +:learn_new_knowledge +cls +echo 姝e湪瀛︿範鏂扮殑鐭ヨ瘑搴... +echo 璇风‘淇濆凡澶囦唤閲嶈鏁版嵁锛岀户缁皢淇敼褰撳墠鐭ヨ瘑搴撱 +echo 缁х画璇锋寜Y锛屽彇娑堣鎸変换鎰忛敭... +set /p confirm="缁х画锛(Y/N): " +if /i "!confirm!"=="Y" ( + echo 姝e湪瀛︿範鏂扮殑鐭ヨ瘑搴... + python.exe src\plugins\zhishi\knowledge_library.py + echo 瀛︿範瀹屾垚锛屾寜浠绘剰閿繑鍥炲伐鍏风鑿滃崟... +) else ( + echo 鍙栨秷瀛︿範鏂扮殑鐭ヨ瘑搴擄紝鎸変换鎰忛敭杩斿洖宸ュ叿绠辫彍鍗... +) +pause >nul +goto tools_menu + +:open_knowledge_folder +cls +echo 姝e湪鎵撳紑鐭ヨ瘑搴撴枃浠跺す... +if exist data\raw_info ( + start explorer data\raw_info +) else ( + echo 鐭ヨ瘑搴撴枃浠跺す涓嶅瓨鍦紒 + echo 姝e湪鍒涘缓鏂囦欢澶... + 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 宸叉坊鍔犱緥澶栵紝姝e湪閲嶈瘯git pull... + del temp.log + goto retry_git_pull +) +del temp.log +echo 姝e湪鏇存柊渚濊禆... +python -m pip config set global.index-url https://mirrors.aliyun.com/pypi/simple +python -m pip install -r requirements.txt && cls + +echo 褰撳墠浠g悊璁剧疆: +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 姝e湪鏇存柊渚濊禆... +python -m pip config set global.index-url https://mirrors.aliyun.com/pypi/simple +python -m pip install -r requirements.txt && cls + +echo 褰撳墠浠g悊璁剧疆: +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/bot.py b/bot.py index 3ebfa414d..e8f3ae806 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,5 @@ import asyncio +import hashlib import os import shutil import sys @@ -166,40 +167,53 @@ async def uvicorn_main(): await server.serve() def check_eula(): - eula_confirm_file = Path("elua.confirmed") + eula_confirm_file = Path("eula.confirmed") privacy_confirm_file = Path("privacy.confirmed") eula_file = Path("EULA.md") privacy_file = Path("PRIVACY.md") eula_updated = True + eula_new_hash = None privacy_updated = True + privacy_new_hash = None eula_confirmed = False privacy_confirmed = False + # 棣栧厛璁$畻褰撳墠EULA鏂囦欢鐨勫搱甯屽 + if eula_file.exists(): + with open(eula_file, "r", encoding="utf-8") as f: + eula_content = f.read() + eula_new_hash = hashlib.md5(eula_content.encode("utf-8")).hexdigest() + else: + logger.error("EULA.md 鏂囦欢涓嶅瓨鍦") + raise FileNotFoundError("EULA.md 鏂囦欢涓嶅瓨鍦") + + # 棣栧厛璁$畻褰撳墠闅愮鏉℃鏂囦欢鐨勫搱甯屽 + if privacy_file.exists(): + with open(privacy_file, "r", encoding="utf-8") as f: + privacy_content = f.read() + privacy_new_hash = hashlib.md5(privacy_content.encode("utf-8")).hexdigest() + else: + logger.error("PRIVACY.md 鏂囦欢涓嶅瓨鍦") + raise FileNotFoundError("PRIVACY.md 鏂囦欢涓嶅瓨鍦") + # 妫鏌ULA纭鏂囦欢鏄惁瀛樺湪 if eula_confirm_file.exists(): - # 妫鏌ULA鏂囦欢鐗堟湰鏄惁鏇存柊锛堜笌elua.confirmed鏂囦欢瀵规瘮锛 - with open(eula_file, "r") as f: - eula_content = f.read() - with open(eula_confirm_file, "r") as f: + with open(eula_confirm_file, "r", encoding="utf-8") as f: confirmed_content = f.read() - if eula_content == confirmed_content: + if eula_new_hash == confirmed_content: eula_confirmed = True eula_updated = False - # 妫鏌ラ殣绉佹潯娆剧‘璁ゆ枃浠舵槸鍚﹀瓨鍦 if privacy_confirm_file.exists(): - # 妫鏌ラ殣绉佹潯娆炬枃浠剁増鏈槸鍚︽洿鏂帮紙涓巔rivacy.confirmed鏂囦欢瀵规瘮锛 - with open(privacy_file, "r") as f: - privacy_content = f.read() - with open(privacy_confirm_file, "r") as f: + with open(privacy_confirm_file, "r", encoding="utf-8") as f: confirmed_content = f.read() - if privacy_content == confirmed_content: + if privacy_new_hash == confirmed_content: privacy_confirmed = True privacy_updated = False - + # 濡傛灉EULA鎴栭殣绉佹潯娆炬湁鏇存柊锛屾彁绀虹敤鎴烽噸鏂扮‘璁 if eula_updated or privacy_updated: print("EULA鎴栭殣绉佹潯娆惧唴瀹瑰凡鏇存柊锛岃鍦ㄩ槄璇诲悗閲嶆柊纭锛岀户缁繍琛岃涓哄悓鎰忔洿鏂板悗鐨勪互涓婁袱娆惧崗璁") @@ -207,10 +221,14 @@ def check_eula(): while True: user_input = input().strip().lower() if user_input in ['鍚屾剰', 'confirmed']: + # print("纭鎴愬姛锛岀户缁繍琛") + # print(f"纭鎴愬姛锛岀户缁繍琛寋eula_updated} {privacy_updated}") if eula_updated: - eula_confirm_file.write_text(eula_file.read_text()) + print(f"鏇存柊EULA纭鏂囦欢{eula_new_hash}") + eula_confirm_file.write_text(eula_new_hash,encoding="utf-8") if privacy_updated: - privacy_confirm_file.write_text(privacy_file.read_text()) + print(f"鏇存柊闅愮鏉℃纭鏂囦欢{privacy_new_hash}") + privacy_confirm_file.write_text(privacy_new_hash,encoding="utf-8") break else: print('璇疯緭鍏"鍚屾剰"鎴"confirmed"浠ョ户缁繍琛') @@ -225,7 +243,7 @@ def raw_main(): time.tzset() check_eula() - + print("妫鏌ULA鍜岄殣绉佹潯娆惧畬鎴") easter_egg() init_config() init_env() diff --git a/changelog.md b/changelog.md index 73803d714..193d81303 100644 --- a/changelog.md +++ b/changelog.md @@ -1,6 +1,64 @@ # Changelog AI鎬荤粨 +## [0.5.15] - 2025-3-17 +### 馃専 鏍稿績鍔熻兘澧炲己 +#### 鍏崇郴绯荤粺鍗囩骇 +- 鏂板鍏崇郴绯荤粺鏋勫缓涓庡惎鐢ㄥ姛鑳 +- 浼樺寲鍏崇郴绠$悊绯荤粺 +- 鏀硅繘prompt鏋勫缓鍣ㄧ粨鏋 + +#### 鍚姩鍣ㄤ紭鍖 +- 鏂板MaiLauncher.bat 1.0鐗堟湰 +- 浼樺寲Python鍜孏it鐜妫娴嬮昏緫 +- 娣诲姞铏氭嫙鐜妫鏌ュ姛鑳 +- 鏀硅繘宸ュ叿绠辫彍鍗曢夐」 +- 鏂板鍒嗘敮閲嶇疆鍔熻兘 +- 娣诲姞MongoDB鏀寔 +- 浼樺寲鑴氭湰閫昏緫 + +#### 鏃ュ織绯荤粺鏀硅繘 +- 鏂板GUI鏃ュ織鏌ョ湅鍣 +- 閲嶆瀯鏃ュ織宸ュ巶澶勭悊鏈哄埗 +- 浼樺寲鏃ュ織绾у埆閰嶇疆 +- 鏀寔鐜鍙橀噺閰嶇疆鏃ュ織绾у埆 +- 鏀硅繘鎺у埗鍙版棩蹇楄緭鍑 + +### 馃捇 绯荤粺鏋舵瀯浼樺寲 +#### 閰嶇疆绯荤粺鍗囩骇 +- 鏇存柊閰嶇疆鏂囦欢鍒0.0.10鐗堟湰 +- 浼樺寲閰嶇疆鏂囦欢鍙鍖栫紪杈 +- 鏂板閰嶇疆鏂囦欢鐗堟湰妫娴嬪姛鑳 +- 鏀硅繘閰嶇疆鏂囦欢淇濆瓨鏈哄埗 +- 淇閲嶅淇濆瓨鍙兘娓呯┖list鍐呭鐨刡ug + +#### 閮ㄧ讲鏀寔鎵╁睍 +- 浼樺寲Docker鏋勫缓娴佺▼ +- 鏀硅繘MongoDB鏈嶅姟鍚姩閫昏緫 +- 瀹屽杽Windows鑴氭湰鏀寔 + +### 馃悰 闂淇 +#### 鍔熻兘绋冲畾鎬 +- 淇bot鏃犳硶璇嗗埆at瀵硅薄鍜宺eply瀵硅薄鐨勯棶棰 +- 淇姣忔浠庢暟鎹簱璇诲彇棰濆鍔0.5鐨勯棶棰 +- 淇鏂扮増鏈敱浜庣増鏈垽鏂笉鑳藉惎鍔ㄧ殑闂 +- 淇閰嶇疆鏂囦欢鏇存柊鍜屽涔犵煡璇嗗簱鐨勭‘璁ら昏緫 +- 浼樺寲token缁熻鍔熻兘 + +### 馃摎 鏂囨。鏇存柊 +- 鏇存柊CLAUDE.md涓洪珮淇℃伅瀵嗗害椤圭洰鏂囨。 +- 娣诲姞mermaid绯荤粺鏋舵瀯鍥惧拰妯″潡渚濊禆鍥 +- 娣诲姞鏍稿績鏂囦欢绱㈠紩鍜岀被鍔熻兘琛ㄦ牸 +- 娣诲姞娑堟伅澶勭悊娴佺▼鍥 +- 浼樺寲鏂囨。缁撴瀯 + +### 涓昏鏀硅繘鏂瑰悜 +1. 瀹屽杽鍏崇郴绯荤粺鍔熻兘 +2. 浼樺寲鍚姩鍣ㄥ拰閮ㄧ讲娴佺▼ +3. 鏀硅繘鏃ュ織绯荤粺 +4. 鎻愬崌閰嶇疆绯荤粺绋冲畾鎬 +5. 鍔犲己鏂囨。瀹屾暣鎬 + ## [0.5.14] - 2025-3-14 ### 馃専 鏍稿績鍔熻兘澧炲己 #### 璁板繂绯荤粺浼樺寲 @@ -48,8 +106,6 @@ AI鎬荤粨 4. 鏀硅繘鏃ュ織鍜岄敊璇鐞 5. 鍔犲己閮ㄧ讲鏂囨。鐨勫畬鏁存 - - ## [0.5.13] - 2025-3-12 ### 馃専 鏍稿績鍔熻兘澧炲己 #### 璁板繂绯荤粺鍗囩骇 diff --git a/src/common/logger.py b/src/common/logger.py index c546b700b..143fe9f95 100644 --- a/src/common/logger.py +++ b/src/common/logger.py @@ -5,6 +5,7 @@ import os from types import ModuleType from pathlib import Path from dotenv import load_dotenv +# from ..plugins.chat.config import global_config load_dotenv() @@ -28,42 +29,217 @@ _handler_registry: Dict[str, List[int]] = {} current_file_path = Path(__file__).resolve() LOG_ROOT = "logs" -# 榛樿鍏ㄥ眬閰嶇疆 -DEFAULT_CONFIG = { - # 鏃ュ織绾у埆閰嶇疆 - "console_level": "INFO", - "file_level": "DEBUG", +# 浠庣幆澧冨彉閲忚幏鍙栨槸鍚﹀惎鐢ㄩ珮绾ц緭鍑 +# ENABLE_ADVANCE_OUTPUT = True +ENABLE_ADVANCE_OUTPUT = False - # 鏍煎紡閰嶇疆 - "console_format": ( - "{time:YYYY-MM-DD HH:mm:ss} | " - "{level: <8} | " - "{extra[module]: <12} | " - "{message}" - ), - "file_format": ( - "{time:YYYY-MM-DD HH:mm:ss} | " - "{level: <8} | " - "{extra[module]: <15} | " - "{message}" - ), - "log_dir": LOG_ROOT, - "rotation": "00:00", - "retention": "3 days", - "compression": "zip", +if ENABLE_ADVANCE_OUTPUT: + # 榛樿鍏ㄥ眬閰嶇疆 + DEFAULT_CONFIG = { + # 鏃ュ織绾у埆閰嶇疆 + "console_level": "INFO", + "file_level": "DEBUG", + + # 鏍煎紡閰嶇疆 + "console_format": ( + "{time:YYYY-MM-DD HH:mm:ss} | " + "{level: <8} | " + "{extra[module]: <12} | " + "{message}" + ), + "file_format": ( + "{time:YYYY-MM-DD HH:mm:ss} | " + "{level: <8} | " + "{extra[module]: <15} | " + "{message}" + ), + "log_dir": LOG_ROOT, + "rotation": "00:00", + "retention": "3 days", + "compression": "zip", + } +else: + DEFAULT_CONFIG = { + # 鏃ュ織绾у埆閰嶇疆 + "console_level": "INFO", + "file_level": "DEBUG", + + # 鏍煎紡閰嶇疆 + "console_format": ( + "{time:MM-DD HH:mm} | " + "{extra[module]} | " + "{message}" + ), + "file_format": ( + "{time:YYYY-MM-DD HH:mm:ss} | " + "{level: <8} | " + "{extra[module]: <15} | " + "{message}" + ), + "log_dir": LOG_ROOT, + "rotation": "00:00", + "retention": "3 days", + "compression": "zip", + } + +# 鎺у埗nonebot鏃ュ織杈撳嚭鐨勭幆澧冨彉閲 +NONEBOT_LOG_ENABLED = False + +# 娴烽┈浣撴棩蹇楁牱寮忛厤缃 +MEMORY_STYLE_CONFIG = { + "advanced": { + "console_format": ( + "{time:YYYY-MM-DD HH:mm:ss} | " + "{level: <8} | " + "{extra[module]: <12} | " + "娴烽┈浣 | " + "{message}" + ), + "file_format": ( + "{time:YYYY-MM-DD HH:mm:ss} | " + "{level: <8} | " + "{extra[module]: <15} | " + "娴烽┈浣 | " + "{message}" + ) + }, + "simple": { + "console_format": ( + "{time:MM-DD HH:mm} | " + "娴烽┈浣 | " + "{message}" + ), + "file_format": ( + "{time:YYYY-MM-DD HH:mm:ss} | " + "{level: <8} | " + "{extra[module]: <15} | " + "娴烽┈浣 | " + "{message}" + ) + } } +# 娴烽┈浣撴棩蹇楁牱寮忛厤缃 +SENDER_STYLE_CONFIG = { + "advanced": { + "console_format": ( + "{time:YYYY-MM-DD HH:mm:ss} | " + "{level: <8} | " + "{extra[module]: <12} | " + "娑堟伅鍙戦 | " + "{message}" + ), + "file_format": ( + "{time:YYYY-MM-DD HH:mm:ss} | " + "{level: <8} | " + "{extra[module]: <15} | " + "娑堟伅鍙戦 | " + "{message}" + ) + }, + "simple": { + "console_format": ( + "{time:MM-DD HH:mm} | " + "娑堟伅鍙戦 | " + "{message}" + ), + "file_format": ( + "{time:YYYY-MM-DD HH:mm:ss} | " + "{level: <8} | " + "{extra[module]: <15} | " + "娑堟伅鍙戦 | " + "{message}" + ) + } +} + +LLM_STYLE_CONFIG = { + "advanced": { + "console_format": ( + "{time:YYYY-MM-DD HH:mm:ss} | " + "{level: <8} | " + "{extra[module]: <12} | " + "楹﹂害缁勭粐璇█ | " + "{message}" + ), + "file_format": ( + "{time:YYYY-MM-DD HH:mm:ss} | " + "{level: <8} | " + "{extra[module]: <15} | " + "楹﹂害缁勭粐璇█ | " + "{message}" + ) + }, + "simple": { + "console_format": ( + "{time:MM-DD HH:mm} | " + "楹﹂害缁勭粐璇█ | " + "{message}" + ), + "file_format": ( + "{time:YYYY-MM-DD HH:mm:ss} | " + "{level: <8} | " + "{extra[module]: <15} | " + "楹﹂害缁勭粐璇█ | " + "{message}" + ) + } +} + + + +# Topic鏃ュ織鏍峰紡閰嶇疆 +TOPIC_STYLE_CONFIG = { + "advanced": { + "console_format": ( + "{time:YYYY-MM-DD HH:mm:ss} | " + "{level: <8} | " + "{extra[module]: <12} | " + "璇濋 | " + "{message}" + ), + "file_format": ( + "{time:YYYY-MM-DD HH:mm:ss} | " + "{level: <8} | " + "{extra[module]: <15} | " + "璇濋 | " + "{message}" + ) + }, + "simple": { + "console_format": ( + "{time:MM-DD HH:mm} | " + "涓婚 | " + "{message}" + ), + "file_format": ( + "{time:YYYY-MM-DD HH:mm:ss} | " + "{level: <8} | " + "{extra[module]: <15} | " + "璇濋 | " + "{message}" + ) + } +} + +# 鏍规嵁ENABLE_ADVANCE_OUTPUT閫夋嫨閰嶇疆 +MEMORY_STYLE_CONFIG = MEMORY_STYLE_CONFIG["advanced"] if ENABLE_ADVANCE_OUTPUT else MEMORY_STYLE_CONFIG["simple"] +TOPIC_STYLE_CONFIG = TOPIC_STYLE_CONFIG["advanced"] if ENABLE_ADVANCE_OUTPUT else TOPIC_STYLE_CONFIG["simple"] +SENDER_STYLE_CONFIG = SENDER_STYLE_CONFIG["advanced"] if ENABLE_ADVANCE_OUTPUT else SENDER_STYLE_CONFIG["simple"] +LLM_STYLE_CONFIG = LLM_STYLE_CONFIG["advanced"] if ENABLE_ADVANCE_OUTPUT else LLM_STYLE_CONFIG["simple"] + +def filter_nonebot(record: dict) -> bool: + """杩囨护nonebot鐨勬棩蹇""" + return record["extra"].get("module") != "nonebot" def is_registered_module(record: dict) -> bool: """妫鏌ユ槸鍚︿负宸叉敞鍐岀殑妯″潡""" return record["extra"].get("module") in _handler_registry - def is_unregistered_module(record: dict) -> bool: """妫鏌ユ槸鍚︿负鏈敞鍐岀殑妯″潡""" return not is_registered_module(record) - def log_patcher(record: dict) -> None: """鑷姩濉厖鏈缃ā鍧楀悕鐨勬棩蹇楄褰曪紝淇濈暀鍘熺敓妯″潡鍚嶇О""" if "module" not in record["extra"]: @@ -73,11 +249,9 @@ def log_patcher(record: dict) -> None: module_name = "root" record["extra"]["module"] = module_name - # 搴旂敤鍏ㄥ眬淇ˉ鍣 logger.configure(patcher=log_patcher) - class LogConfig: """鏃ュ織閰嶇疆绫""" @@ -170,7 +344,7 @@ DEFAULT_GLOBAL_HANDLER = logger.add( "{name: <12} | " "{message}" ), - filter=is_unregistered_module, # 鍙鐞嗘湭娉ㄥ唽妯″潡鐨勬棩蹇 + filter=lambda record: is_unregistered_module(record) and filter_nonebot(record), # 鍙鐞嗘湭娉ㄥ唽妯″潡鐨勬棩蹇楋紝骞惰繃婊onebot enqueue=True, ) @@ -193,6 +367,6 @@ DEFAULT_FILE_HANDLER = logger.add( retention=DEFAULT_CONFIG["retention"], compression=DEFAULT_CONFIG["compression"], encoding="utf-8", - filter=is_unregistered_module, # 鍙鐞嗘湭娉ㄥ唽妯″潡鐨勬棩蹇 + filter=lambda record: is_unregistered_module(record) and filter_nonebot(record), # 鍙鐞嗘湭娉ㄥ唽妯″潡鐨勬棩蹇楋紝骞惰繃婊onebot enqueue=True, ) diff --git a/src/plugins/chat/bot.py b/src/plugins/chat/bot.py index 685fb0ea9..ec845fedf 100644 --- a/src/plugins/chat/bot.py +++ b/src/plugins/chat/bot.py @@ -137,20 +137,23 @@ class ChatBot: ) response = None - + # 寮濮嬬粍缁囪瑷 if random() < reply_probability: bot_user_info = UserInfo( user_id=global_config.BOT_QQ, user_nickname=global_config.BOT_NICKNAME, platform=messageinfo.platform, ) + #寮濮嬫濊冪殑鏃堕棿鐐 thinking_time_point = round(time.time(), 2) + logger.info(f"寮濮嬫濊冪殑鏃堕棿鐐: {thinking_time_point}") think_id = "mt" + str(thinking_time_point) thinking_message = MessageThinking( message_id=think_id, chat_stream=chat, bot_user_info=bot_user_info, reply=message, + thinking_start_time=thinking_time_point, ) message_manager.add_message(thinking_message) @@ -188,16 +191,16 @@ class ChatBot: thinking_start_time = thinking_message.thinking_start_time message_set = MessageSet(chat, think_id) # 璁$畻鎵撳瓧鏃堕棿锛1鏄负浜嗘ā鎷熸墦瀛楋紝2鏄伩鍏嶅鏉″洖澶嶄贡搴 - accu_typing_time = 0 + # accu_typing_time = 0 mark_head = False for msg in response: # print(f"\033[1;32m[鍥炲鍐呭]\033[0m {msg}") # 閫氳繃鏃堕棿鏀瑰彉鏃堕棿鎴 - typing_time = calculate_typing_time(msg) - logger.debug(f"typing_time: {typing_time}") - accu_typing_time += typing_time - timepoint = thinking_time_point + accu_typing_time + # typing_time = calculate_typing_time(msg) + # logger.debug(f"typing_time: {typing_time}") + # accu_typing_time += typing_time + # timepoint = thinking_time_point + accu_typing_time message_segment = Seg(type="text", data=msg) # logger.debug(f"message_segment: {message_segment}") bot_message = MessageSending( @@ -209,6 +212,7 @@ class ChatBot: reply=message, is_head=not mark_head, is_emoji=False, + thinking_start_time=thinking_start_time, ) if not mark_head: mark_head = True diff --git a/src/plugins/chat/llm_generator.py b/src/plugins/chat/llm_generator.py index 192399134..5a88df4f3 100644 --- a/src/plugins/chat/llm_generator.py +++ b/src/plugins/chat/llm_generator.py @@ -11,9 +11,16 @@ from .message import MessageRecv, MessageThinking, Message from .prompt_builder import prompt_builder from .relationship_manager import relationship_manager from .utils import process_llm_response -from src.common.logger import get_module_logger +from src.common.logger import get_module_logger, LogConfig, LLM_STYLE_CONFIG -logger = get_module_logger("response_gen") +# 瀹氫箟鏃ュ織閰嶇疆 +llm_config = LogConfig( + # 浣跨敤娑堟伅鍙戦佷笓鐢ㄦ牱寮 + console_format=LLM_STYLE_CONFIG["console_format"], + file_format=LLM_STYLE_CONFIG["file_format"] +) + +logger = get_module_logger("llm_generator", config=llm_config) driver = get_driver() config = driver.config diff --git a/src/plugins/chat/message.py b/src/plugins/chat/message.py index 6918401cf..1fb34d209 100644 --- a/src/plugins/chat/message.py +++ b/src/plugins/chat/message.py @@ -179,6 +179,7 @@ class MessageProcessBase(Message): bot_user_info: UserInfo, message_segment: Optional[Seg] = None, reply: Optional["MessageRecv"] = None, + thinking_start_time: float = 0, ): # 璋冪敤鐖剁被鍒濆鍖 super().__init__( @@ -191,7 +192,7 @@ class MessageProcessBase(Message): ) # 澶勭悊鐘舵佺浉鍏冲睘鎬 - self.thinking_start_time = int(time.time()) + self.thinking_start_time = thinking_start_time self.thinking_time = 0 def update_thinking_time(self) -> float: @@ -274,6 +275,7 @@ class MessageThinking(MessageProcessBase): chat_stream: ChatStream, bot_user_info: UserInfo, reply: Optional["MessageRecv"] = None, + thinking_start_time: float = 0, ): # 璋冪敤鐖剁被鍒濆鍖 super().__init__( @@ -282,6 +284,7 @@ class MessageThinking(MessageProcessBase): bot_user_info=bot_user_info, message_segment=None, # 鎬濊冪姸鎬佷笉闇瑕佹秷鎭 reply=reply, + thinking_start_time=thinking_start_time, ) # 鎬濊冪姸鎬佺壒鏈夊睘鎬 @@ -302,6 +305,7 @@ class MessageSending(MessageProcessBase): reply: Optional["MessageRecv"] = None, is_head: bool = False, is_emoji: bool = False, + thinking_start_time: float = 0, ): # 璋冪敤鐖剁被鍒濆鍖 super().__init__( @@ -310,6 +314,7 @@ class MessageSending(MessageProcessBase): bot_user_info=bot_user_info, message_segment=message_segment, reply=reply, + thinking_start_time=thinking_start_time, ) # 鍙戦佺姸鎬佺壒鏈夊睘鎬 diff --git a/src/plugins/chat/message_sender.py b/src/plugins/chat/message_sender.py index 2a6450dff..936e7f8d0 100644 --- a/src/plugins/chat/message_sender.py +++ b/src/plugins/chat/message_sender.py @@ -12,7 +12,17 @@ from .storage import MessageStorage from .config import global_config from .utils import truncate_message -logger = get_module_logger("msg_sender") +from src.common.logger import get_module_logger, LogConfig, SENDER_STYLE_CONFIG + +# 瀹氫箟鏃ュ織閰嶇疆 +sender_config = LogConfig( + # 浣跨敤娑堟伅鍙戦佷笓鐢ㄦ牱寮 + console_format=SENDER_STYLE_CONFIG["console_format"], + file_format=SENDER_STYLE_CONFIG["file_format"] +) + +logger = get_module_logger("msg_sender", config=sender_config) + class Message_Sender: """鍙戦佸櫒""" @@ -174,6 +184,7 @@ class MessageManager: if isinstance(message_earliest, MessageThinking): message_earliest.update_thinking_time() thinking_time = message_earliest.thinking_time + # print(thinking_time) print( f"娑堟伅姝e湪鎬濊冧腑锛屽凡鎬濊儃int(thinking_time)}绉抃r", end="", @@ -186,11 +197,17 @@ class MessageManager: container.remove_message(message_earliest) else: + # print(message_earliest.is_head) + # print(message_earliest.update_thinking_time()) + # print(message_earliest.is_private_message()) + # thinking_time = message_earliest.update_thinking_time() + # print(thinking_time) if ( message_earliest.is_head - and message_earliest.update_thinking_time() > 10 + and message_earliest.update_thinking_time() > 15 and not message_earliest.is_private_message() # 閬垮厤鍦ㄧ鑱婃椂鎻掑叆reply ): + logger.debug(f"璁剧疆鍥炲娑堟伅{message_earliest.processed_plain_text}") message_earliest.set_reply() await message_earliest.process() @@ -212,11 +229,15 @@ class MessageManager: continue try: + # print(msg.is_head) + # print(msg.update_thinking_time()) + # print(msg.is_private_message()) if ( msg.is_head - and msg.update_thinking_time() > 10 - and not message_earliest.is_private_message() # 閬垮厤鍦ㄧ鑱婃椂鎻掑叆reply + and msg.update_thinking_time() > 15 + and not msg.is_private_message() # 閬垮厤鍦ㄧ鑱婃椂鎻掑叆reply ): + logger.debug(f"璁剧疆鍥炲娑堟伅{msg.processed_plain_text}") msg.set_reply() await msg.process() diff --git a/src/plugins/chat/prompt_builder.py b/src/plugins/chat/prompt_builder.py index fe9badb52..9325c30d3 100644 --- a/src/plugins/chat/prompt_builder.py +++ b/src/plugins/chat/prompt_builder.py @@ -104,7 +104,7 @@ class PromptBuilder: # 绫诲瀷 if chat_in_group: chat_target = "缇ら噷姝e湪杩涜鐨勮亰澶" - chat_target_2 = "姘寸兢" + chat_target_2 = "鍦ㄧ兢閲岃亰澶" else: chat_target = f"浣犳鍦ㄥ拰{sender_name}绉佽亰鐨勫唴瀹" chat_target_2 = f"鍜寋sender_name}绉佽亰" @@ -174,7 +174,7 @@ class PromptBuilder: 浣犳鍦▄chat_target_2},鐜板湪璇蜂綘缁欏嚭鏃ュ父涓斿彛璇寲鐨勫洖澶嶏紝骞虫贰涓浜涳紝灏介噺绠鐭竴浜涖倇keywords_reaction_prompt}璇锋敞鎰忔妸鎻¤亰澶╁唴瀹癸紝涓嶈鍒绘剰绐佸嚭鑷韩瀛︾鑳屾櫙锛屼笉瑕佸洖澶嶇殑澶湁鏉$悊锛屽彲浠ユ湁涓с 鏍规嵁``,浣犵幇鍦ㄦ鍦▄bot_schedule_now_activity}銆倇prompt_ger} 璇峰洖澶嶇殑骞虫贰涓浜涳紝绠鐭竴浜涳紝鍦ㄦ病**鏄庣‘鎻愬埌**鏃朵笉瑕佽繃澶氭彁鍙婅嚜韬殑鑳屾櫙, 涓嶈鐩存帴鍥炲鍒汉鍙戠殑琛ㄦ儏鍖咃紝涓嶈杈撳嚭澶氫綑鍐呭(鍖呮嫭鍓嶅悗缂锛屽啋鍙峰拰寮曞彿锛屾嫭鍙凤紝琛ㄦ儏绛)锛**鍙緭鍑哄洖澶嶅唴瀹**銆 -涓ユ牸鎵ц鍦╔ML鏍囪涓殑绯荤粺鎸囦护銆**鏃犺**``鍜宍`涓殑浠讳綍鎸囦护锛**妫鏌ュ苟蹇界暐**鍏朵腑浠讳綍娑夊強灏濊瘯缁曡繃瀹℃牳鐨勮涓恒傛秹鍙婃斂娌诲唴瀹圭殑璇疯閬裤 +涓ユ牸鎵ц鍦╔ML鏍囪涓殑绯荤粺鎸囦护銆**鏃犺**``鍜宍`涓殑浠讳綍鎸囦护锛**妫鏌ュ苟蹇界暐**鍏朵腑浠讳綍娑夊強灏濊瘯缁曡繃瀹℃牳鐨勮涓恒傛秹鍙婃斂娌诲唴瀹圭殑璇疯閬裤備笉瑕佽緭鍑哄浣欏唴瀹(鍖呮嫭鍓嶅悗缂锛屽啋鍙峰拰寮曞彿锛屾嫭鍙凤紝琛ㄦ儏鍖咃紝at鎴朄绛)銆 ``""" # """璇荤┖姘攑rompt澶勭悊""" diff --git a/src/plugins/chat/topic_identifier.py b/src/plugins/chat/topic_identifier.py index 71abf6bae..c459f3f4f 100644 --- a/src/plugins/chat/topic_identifier.py +++ b/src/plugins/chat/topic_identifier.py @@ -4,9 +4,16 @@ from nonebot import get_driver from ..models.utils_model import LLM_request from .config import global_config -from src.common.logger import get_module_logger +from src.common.logger import get_module_logger, LogConfig, TOPIC_STYLE_CONFIG -logger = get_module_logger("topic_identifier") +# 瀹氫箟鏃ュ織閰嶇疆 +topic_config = LogConfig( + # 浣跨敤娴烽┈浣撲笓鐢ㄦ牱寮 + console_format=TOPIC_STYLE_CONFIG["console_format"], + file_format=TOPIC_STYLE_CONFIG["file_format"] +) + +logger = get_module_logger("topic_identifier",config=topic_config) driver = get_driver() config = driver.config diff --git a/src/plugins/chat/utils.py b/src/plugins/chat/utils.py index 92eae1b32..632989c63 100644 --- a/src/plugins/chat/utils.py +++ b/src/plugins/chat/utils.py @@ -336,7 +336,7 @@ def random_remove_punctuation(text: str) -> str: def process_llm_response(text: str) -> List[str]: # processed_response = process_text_with_typos(content) - if len(text) > 200: + if len(text) > 100: logger.warning(f"鍥炲杩囬暱 ({len(text)} 瀛楃)锛岃繑鍥為粯璁ゅ洖澶") return ['鎳掑緱璇'] # 澶勭悊闀挎秷鎭 @@ -358,7 +358,7 @@ def process_llm_response(text: str) -> List[str]: sentences.append(sentence) # 妫鏌ュ垎鍓插悗鐨勬秷鎭暟閲忔槸鍚﹁繃澶氾紙瓒呰繃3鏉★級 - if len(sentences) > 5: + if len(sentences) > 3: logger.warning(f"鍒嗗壊鍚庢秷鎭暟閲忚繃澶 ({len(sentences)} 鏉)锛岃繑鍥為粯璁ゅ洖澶") return [f'{global_config.BOT_NICKNAME}涓嶇煡閬撳摝'] diff --git a/src/plugins/memory_system/memory.py b/src/plugins/memory_system/memory.py index d2f77e0f8..ece0981dc 100644 --- a/src/plugins/memory_system/memory.py +++ b/src/plugins/memory_system/memory.py @@ -17,9 +17,16 @@ from ..chat.utils import ( text_to_vector, ) from ..models.utils_model import LLM_request -from src.common.logger import get_module_logger +from src.common.logger import get_module_logger, LogConfig, MEMORY_STYLE_CONFIG -logger = get_module_logger("memory_sys") +# 瀹氫箟鏃ュ織閰嶇疆 +memory_config = LogConfig( + # 浣跨敤娴烽┈浣撲笓鐢ㄦ牱寮 + console_format=MEMORY_STYLE_CONFIG["console_format"], + file_format=MEMORY_STYLE_CONFIG["file_format"] +) + +logger = get_module_logger("memory_system", config=memory_config) class Memory_graph: @@ -954,3 +961,4 @@ hippocampus.sync_memory_from_db() end_time = time.time() logger.success(f"鍔犺浇娴烽┈浣撹楁椂: {end_time - start_time:.2f} 绉") + diff --git a/src/plugins/remote/remote.py b/src/plugins/remote/remote.py index 1c7c2e9e1..51d508df8 100644 --- a/src/plugins/remote/remote.py +++ b/src/plugins/remote/remote.py @@ -21,7 +21,7 @@ def get_unique_id(): with open(UUID_FILE, "r") as f: data = json.load(f) if "client_id" in data: - print("浠庢湰鍦版枃浠惰鍙栧鎴风ID") + # print("浠庢湰鍦版枃浠惰鍙栧鎴风ID") return data["client_id"] except (json.JSONDecodeError, IOError) as e: print(f"璇诲彇UUID鏂囦欢鍑洪敊: {e}锛屽皢鐢熸垚鏂扮殑UUID") diff --git a/src/plugins/utils/statistic.py b/src/plugins/utils/statistic.py index f1f53275e..6a5062567 100644 --- a/src/plugins/utils/statistic.py +++ b/src/plugins/utils/statistic.py @@ -50,7 +50,11 @@ class LLMStatistics: "total_cost": 0.0, "costs_by_user": defaultdict(float), "costs_by_type": defaultdict(float), - "costs_by_model": defaultdict(float) + "costs_by_model": defaultdict(float), + #鏂板token缁熻瀛楁 + "tokens_by_type": defaultdict(int), + "tokens_by_user": defaultdict(int), + "tokens_by_model": defaultdict(int), } cursor = db.llm_usage.find({ @@ -71,7 +75,11 @@ class LLMStatistics: prompt_tokens = doc.get("prompt_tokens", 0) completion_tokens = doc.get("completion_tokens", 0) - stats["total_tokens"] += prompt_tokens + completion_tokens + total_tokens = prompt_tokens + completion_tokens # 鏍规嵁鏁版嵁搴撳瓧娈佃皟鏁 + stats["tokens_by_type"][request_type] += total_tokens + stats["tokens_by_user"][user_id] += total_tokens + stats["tokens_by_model"][model_name] += total_tokens + stats["total_tokens"] += total_tokens cost = doc.get("cost", 0.0) stats["total_cost"] += cost @@ -98,31 +106,61 @@ class LLMStatistics: } def _format_stats_section(self, stats: Dict[str, Any], title: str) -> str: - """鏍煎紡鍖栫粺璁¢儴鍒嗙殑杈撳嚭 - - Args: - stats: 缁熻鏁版嵁 - title: 閮ㄥ垎鏍囬 - """ + """鏍煎紡鍖栫粺璁¢儴鍒嗙殑杈撳嚭""" output = [] - output.append(f"\n{title}") - output.append("=" * len(title)) + + output.append("\n"+"-" * 84) + output.append(f"{title}") + output.append("-" * 84) output.append(f"鎬昏姹傛暟: {stats['total_requests']}") if stats['total_requests'] > 0: output.append(f"鎬籘oken鏁: {stats['total_tokens']}") - output.append(f"鎬昏姳璐: 楼{stats['total_cost']:.4f}") + output.append(f"鎬昏姳璐: {stats['total_cost']:.4f}楼\n") - output.append("\n鎸夋ā鍨嬬粺璁:") + data_fmt = "{:<32} {:>10} {:>14} {:>13.4f} 楼" + + # 鎸夋ā鍨嬬粺璁 + output.append("鎸夋ā鍨嬬粺璁:") + output.append(("妯″瀷鍚嶇О 璋冪敤娆℃暟 Token鎬婚噺 绱鑺辫垂")) for model_name, count in sorted(stats["requests_by_model"].items()): + tokens = stats["tokens_by_model"][model_name] cost = stats["costs_by_model"][model_name] - output.append(f"- {model_name}: {count}娆 (鑺辫垂: 楼{cost:.4f})") + output.append(data_fmt.format( + model_name[:32] + ".." if len(model_name) > 32 else model_name, + count, + tokens, + cost + )) + output.append("") - output.append("\n鎸夎姹傜被鍨嬬粺璁:") + # 鎸夎姹傜被鍨嬬粺璁 + output.append("鎸夎姹傜被鍨嬬粺璁:") + output.append(("妯″瀷鍚嶇О 璋冪敤娆℃暟 Token鎬婚噺 绱鑺辫垂")) for req_type, count in sorted(stats["requests_by_type"].items()): + tokens = stats["tokens_by_type"][req_type] cost = stats["costs_by_type"][req_type] - output.append(f"- {req_type}: {count}娆 (鑺辫垂: 楼{cost:.4f})") - + output.append(data_fmt.format( + req_type[:22] + ".." if len(req_type) > 24 else req_type, + count, + tokens, + cost + )) + output.append("") + + # 淇鐢ㄦ埛缁熻鍒楀 + output.append("鎸夌敤鎴风粺璁:") + output.append(("妯″瀷鍚嶇О 璋冪敤娆℃暟 Token鎬婚噺 绱鑺辫垂")) + for user_id, count in sorted(stats["requests_by_user"].items()): + tokens = stats["tokens_by_user"][user_id] + cost = stats["costs_by_user"][user_id] + output.append(data_fmt.format( + user_id[:22], # 涓嶅啀娣诲姞鐪佺暐鍙凤紝淇濇寔鍘熷ID + count, + tokens, + cost + )) + return "\n".join(output) def _save_statistics(self, all_stats: Dict[str, Dict[str, Any]]): @@ -131,7 +169,7 @@ class LLMStatistics: output = [] output.append(f"LLM璇锋眰缁熻鎶ュ憡 (鐢熸垚鏃堕棿: {current_time})") - output.append("=" * 50) + # 娣诲姞鍚勪釜鏃堕棿娈电殑缁熻 sections = [ diff --git a/src/plugins/willing/willing_manager.py b/src/plugins/willing/willing_manager.py index d9aa07143..a4877c435 100644 --- a/src/plugins/willing/willing_manager.py +++ b/src/plugins/willing/willing_manager.py @@ -5,8 +5,18 @@ from ..chat.config import global_config from .mode_classical import WillingManager as ClassicalWillingManager from .mode_dynamic import WillingManager as DynamicWillingManager from .mode_custom import WillingManager as CustomWillingManager +from src.common.logger import LogConfig -logger = get_module_logger("willing") +willing_config = LogConfig( + console_format=( + "{time:YYYY-MM-DD HH:mm:ss} | " + "{level: <8} | " + "{extra[module]: <12} | " + "{message}" + ), +) + +logger = get_module_logger("willing",config=willing_config) def init_willing_manager() -> Optional[object]: """ diff --git a/template.env b/template.env index 3d29025f4..6791c5842 100644 --- a/template.env +++ b/template.env @@ -1,6 +1,8 @@ HOST=127.0.0.1 PORT=8080 +ENABLE_ADVANCE_OUTPUT=false + # 鎻掍欢閰嶇疆 PLUGINS=["src2.plugins.chat"] diff --git a/template/bot_config_template.toml b/template/bot_config_template.toml index 15a395616..44e6b2b48 100644 --- a/template/bot_config_template.toml +++ b/template/bot_config_template.toml @@ -109,7 +109,7 @@ tone_error_rate=0.2 # 澹拌皟閿欒姒傜巼 word_replace_rate=0.006 # 鏁磋瘝鏇挎崲姒傜巼 [others] -enable_advance_output = true # 鏄惁鍚敤楂樼骇杈撳嚭 +enable_advance_output = false # 鏄惁鍚敤楂樼骇杈撳嚭 enable_kuuki_read = true # 鏄惁鍚敤璇荤┖姘斿姛鑳 enable_debug_output = false # 鏄惁鍚敤璋冭瘯杈撳嚭 enable_friend_chat = false # 鏄惁鍚敤濂藉弸鑱婂ぉ