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=[92m"
-) else if "!BRANCH!"=="main-fix" (
- set "BRANCH_COLOR=[91m"
-@REM ) else if "%BRANCH%"=="stable-dev" (
-@REM set "BRANCH_COLOR=[96m"
-) else (
- set "BRANCH_COLOR=[93m"
-)
-
-@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%[0m
-echo 当前Python环境: [96m!PYTHON_HOME![0m
-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%[0m
-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. 切换到[92mmain[0m
-echo 2. 切换到[91mmain-fix[0m
-echo 请输入要切换到的分支:
-set /p branch_name="分支名: "
-if "%branch_name%"=="" set branch_name=main
-if "%branch_name%"=="main" (
- set "BRANCH_COLOR=[92m"
-) else if "%branch_name%"=="main-fix" (
- set "BRANCH_COLOR=[91m"
-@REM ) else if "%branch_name%"=="stable-dev" (
-@REM set "BRANCH_COLOR=[96m"
-) else if "%branch_name%"=="1" (
- set "BRANCH_COLOR=[92m"
- set "branch_name=main"
-) else if "%branch_name%"=="2" (
- set "BRANCH_COLOR=[91m"
- 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%[0m
-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=[92m"
+) else if "!BRANCH!"=="main-fix" (
+ set "BRANCH_COLOR=[91m"
+@REM ) else if "%BRANCH%"=="stable-dev" (
+@REM set "BRANCH_COLOR=[96m"
+) else (
+ set "BRANCH_COLOR=[93m"
+)
+
+@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%[0m
+echo 褰撳墠Python鐜: [96m!PYTHON_HOME![0m
+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%[0m
+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. 鍒囨崲鍒[92mmain[0m
+echo 2. 鍒囨崲鍒[91mmain-fix[0m
+echo 璇疯緭鍏ヨ鍒囨崲鍒扮殑鍒嗘敮:
+set /p branch_name="鍒嗘敮鍚: "
+if "%branch_name%"=="" set branch_name=main
+if "%branch_name%"=="main" (
+ set "BRANCH_COLOR=[92m"
+) else if "%branch_name%"=="main-fix" (
+ set "BRANCH_COLOR=[91m"
+@REM ) else if "%branch_name%"=="stable-dev" (
+@REM set "BRANCH_COLOR=[96m"
+) else if "%branch_name%"=="1" (
+ set "BRANCH_COLOR=[92m"
+ set "branch_name=main"
+) else if "%branch_name%"=="2" (
+ set "BRANCH_COLOR=[91m"
+ 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%[0m
+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 # 鏄惁鍚敤濂藉弸鑱婂ぉ