Merge branch 'debug' into debug
This commit is contained in:
3
.github/workflows/docker-image.yml
vendored
3
.github/workflows/docker-image.yml
vendored
@@ -5,6 +5,7 @@ on:
|
|||||||
branches:
|
branches:
|
||||||
- main
|
- main
|
||||||
- debug # 新增 debug 分支触发
|
- debug # 新增 debug 分支触发
|
||||||
|
- stable-dev
|
||||||
tags:
|
tags:
|
||||||
- 'v*'
|
- 'v*'
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
@@ -34,6 +35,8 @@ jobs:
|
|||||||
echo "tags=${{ secrets.DOCKERHUB_USERNAME }}/maimbot:main,${{ secrets.DOCKERHUB_USERNAME }}/maimbot:latest" >> $GITHUB_OUTPUT
|
echo "tags=${{ secrets.DOCKERHUB_USERNAME }}/maimbot:main,${{ secrets.DOCKERHUB_USERNAME }}/maimbot:latest" >> $GITHUB_OUTPUT
|
||||||
elif [ "${{ github.ref }}" == "refs/heads/debug" ]; then
|
elif [ "${{ github.ref }}" == "refs/heads/debug" ]; then
|
||||||
echo "tags=${{ secrets.DOCKERHUB_USERNAME }}/maimbot:debug" >> $GITHUB_OUTPUT
|
echo "tags=${{ secrets.DOCKERHUB_USERNAME }}/maimbot:debug" >> $GITHUB_OUTPUT
|
||||||
|
elif [ "${{ github.ref }}" == "refs/heads/stable-dev" ]; then
|
||||||
|
echo "tags=${{ secrets.DOCKERHUB_USERNAME }}/maimbot:stable-dev" >> $GITHUB_OUTPUT
|
||||||
fi
|
fi
|
||||||
|
|
||||||
- name: Build and Push Docker Image
|
- name: Build and Push Docker Image
|
||||||
|
|||||||
13
README.md
13
README.md
@@ -50,15 +50,18 @@
|
|||||||
|
|
||||||
### 部署方式
|
### 部署方式
|
||||||
|
|
||||||
如果你不知道Docker是什么,建议寻找相关教程或使用手动部署(现在不建议使用docker,更新慢,可能不适配)
|
- 📦 **Windows 一键傻瓜式部署**:请运行项目根目录中的 ```run.bat```,部署完成后请参照后续配置指南进行配置
|
||||||
|
|
||||||
|
|
||||||
|
- [📦 Windows 手动部署指南 ](docs/manual_deploy_windows.md)
|
||||||
|
|
||||||
|
- [📦 Linux 手动部署指南 ](docs/manual_deploy_linux.md)
|
||||||
|
|
||||||
|
如果你不知道Docker是什么,建议寻找相关教程或使用手动部署 **(现在不建议使用docker,更新慢,可能不适配)**
|
||||||
|
|
||||||
- [🐳 Docker部署指南](docs/docker_deploy.md)
|
- [🐳 Docker部署指南](docs/docker_deploy.md)
|
||||||
|
|
||||||
- [📦 手动部署指南 Windows](docs/manual_deploy_windows.md)
|
|
||||||
|
|
||||||
- [📦 手动部署指南 Linux](docs/manual_deploy_linux.md)
|
|
||||||
|
|
||||||
- 📦 Windows 一键傻瓜式部署,请运行项目根目录中的 ```run.bat```,部署完成后请参照后续配置指南进行配置
|
|
||||||
|
|
||||||
### 配置说明
|
### 配置说明
|
||||||
|
|
||||||
|
|||||||
@@ -58,12 +58,12 @@ key = "SILICONFLOW_KEY" # 用同一张门票就可以啦
|
|||||||
|
|
||||||
```toml
|
```toml
|
||||||
[model.llm_reasoning]
|
[model.llm_reasoning]
|
||||||
name = "Pro/deepseek-ai/DeepSeek-R1"
|
name = "deepseek-reasoner" # 改成对应的模型名称,这里为DeepseekR1
|
||||||
base_url = "DEEP_SEEK_BASE_URL" # 改成去DeepSeek游乐园
|
base_url = "DEEP_SEEK_BASE_URL" # 改成去DeepSeek游乐园
|
||||||
key = "DEEP_SEEK_KEY" # 用DeepSeek的门票
|
key = "DEEP_SEEK_KEY" # 用DeepSeek的门票
|
||||||
|
|
||||||
[model.llm_normal]
|
[model.llm_normal]
|
||||||
name = "Pro/deepseek-ai/DeepSeek-V3"
|
name = "deepseek-chat" # 改成对应的模型名称,这里为DeepseekV3
|
||||||
base_url = "DEEP_SEEK_BASE_URL" # 也去DeepSeek游乐园
|
base_url = "DEEP_SEEK_BASE_URL" # 也去DeepSeek游乐园
|
||||||
key = "DEEP_SEEK_KEY" # 用同一张DeepSeek门票
|
key = "DEEP_SEEK_KEY" # 用同一张DeepSeek门票
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ key = "SILICONFLOW_KEY" # 引用.env.prod中定义的密钥
|
|||||||
|
|
||||||
```toml
|
```toml
|
||||||
[model.llm_reasoning]
|
[model.llm_reasoning]
|
||||||
name = "Pro/deepseek-ai/DeepSeek-R1"
|
name = "deepseek-reasoner" # 改成对应的模型名称,这里为DeepseekR1
|
||||||
base_url = "DEEP_SEEK_BASE_URL" # 切换为DeepSeek服务
|
base_url = "DEEP_SEEK_BASE_URL" # 切换为DeepSeek服务
|
||||||
key = "DEEP_SEEK_KEY" # 使用DeepSeek密钥
|
key = "DEEP_SEEK_KEY" # 使用DeepSeek密钥
|
||||||
```
|
```
|
||||||
@@ -57,14 +57,14 @@ CHAT_ANY_WHERE_KEY=your_key
|
|||||||
CHAT_ANY_WHERE_BASE_URL=https://api.chatanywhere.tech/v1
|
CHAT_ANY_WHERE_BASE_URL=https://api.chatanywhere.tech/v1
|
||||||
|
|
||||||
# 服务配置
|
# 服务配置
|
||||||
# 如果使用Docker部署,需要改成0.0.0.0,否则QQ消息无法传入
|
|
||||||
HOST=127.0.0.1
|
HOST=127.0.0.1 # 如果使用Docker部署,需要改成0.0.0.0,否则QQ消息无法传入
|
||||||
PORT=8080
|
PORT=8080 # 与反向端口相同
|
||||||
|
|
||||||
# 数据库配置
|
# 数据库配置
|
||||||
# 如果使用Docker部署,需要改成数据库容器的名字,默认是mongodb
|
MONGODB_HOST=127.0.0.1 # 如果使用Docker部署,需要改成数据库容器的名字,默认是mongodb
|
||||||
MONGODB_HOST=127.0.0.1
|
MONGODB_PORT=27017 # MongoDB端口
|
||||||
MONGODB_PORT=27017
|
|
||||||
DATABASE_NAME=MegBot
|
DATABASE_NAME=MegBot
|
||||||
# 数据库认证信息,如果需要认证就取消注释并填写下面三行
|
# 数据库认证信息,如果需要认证就取消注释并填写下面三行
|
||||||
# MONGODB_USERNAME = ""
|
# MONGODB_USERNAME = ""
|
||||||
|
|||||||
2
run.bat
2
run.bat
@@ -3,7 +3,7 @@ chcp 65001
|
|||||||
if not exist "venv" (
|
if not exist "venv" (
|
||||||
python -m venv venv
|
python -m venv venv
|
||||||
call venv\Scripts\activate.bat
|
call venv\Scripts\activate.bat
|
||||||
pip install -i https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple --upgrade -r requirements.txt
|
pip install -i https://mirrors.aliyun.com/pypi/simple --upgrade -r requirements.txt
|
||||||
) else (
|
) else (
|
||||||
call venv\Scripts\activate.bat
|
call venv\Scripts\activate.bat
|
||||||
)
|
)
|
||||||
|
|||||||
2
run.py
2
run.py
@@ -107,6 +107,8 @@ def install_napcat():
|
|||||||
napcat_filename = input(
|
napcat_filename = input(
|
||||||
"下载完成后请把文件复制到此文件夹,并将**不包含后缀的文件名**输入至此窗口,如 NapCat.32793.Shell:"
|
"下载完成后请把文件复制到此文件夹,并将**不包含后缀的文件名**输入至此窗口,如 NapCat.32793.Shell:"
|
||||||
)
|
)
|
||||||
|
if(napcat_filename[-4:] == ".zip"):
|
||||||
|
napcat_filename = napcat_filename[:-4]
|
||||||
extract_files(napcat_filename + ".zip", "napcat")
|
extract_files(napcat_filename + ".zip", "napcat")
|
||||||
print("NapCat 安装完成")
|
print("NapCat 安装完成")
|
||||||
os.remove(napcat_filename + ".zip")
|
os.remove(napcat_filename + ".zip")
|
||||||
|
|||||||
@@ -245,8 +245,9 @@ class EmojiManager:
|
|||||||
logger.info(f"其不满足过滤规则,被剔除 {check}")
|
logger.info(f"其不满足过滤规则,被剔除 {check}")
|
||||||
continue
|
continue
|
||||||
logger.info(f"check通过 {check}")
|
logger.info(f"check通过 {check}")
|
||||||
embedding = await get_embedding(discription)
|
|
||||||
if discription is not None:
|
if discription is not None:
|
||||||
|
embedding = await get_embedding(discription)
|
||||||
# 准备数据库记录
|
# 准备数据库记录
|
||||||
emoji_record = {
|
emoji_record = {
|
||||||
'filename': filename,
|
'filename': filename,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
from .config import global_config
|
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
|
from .config import global_config
|
||||||
|
|
||||||
|
|
||||||
class WillingManager:
|
class WillingManager:
|
||||||
@@ -8,13 +8,18 @@ class WillingManager:
|
|||||||
self.group_reply_willing = {} # 存储每个群的回复意愿
|
self.group_reply_willing = {} # 存储每个群的回复意愿
|
||||||
self._decay_task = None
|
self._decay_task = None
|
||||||
self._started = False
|
self._started = False
|
||||||
|
self.min_reply_willing = 0.01
|
||||||
|
self.attenuation_coefficient = 0.75
|
||||||
|
|
||||||
async def _decay_reply_willing(self):
|
async def _decay_reply_willing(self):
|
||||||
"""定期衰减回复意愿"""
|
"""定期衰减回复意愿"""
|
||||||
while True:
|
while True:
|
||||||
await asyncio.sleep(5)
|
await asyncio.sleep(5)
|
||||||
for group_id in self.group_reply_willing:
|
for group_id in self.group_reply_willing:
|
||||||
self.group_reply_willing[group_id] = max(0, self.group_reply_willing[group_id] * 0.6)
|
self.group_reply_willing[group_id] = max(
|
||||||
|
self.min_reply_willing,
|
||||||
|
self.group_reply_willing[group_id] * self.attenuation_coefficient
|
||||||
|
)
|
||||||
|
|
||||||
def get_willing(self, group_id: int) -> float:
|
def get_willing(self, group_id: int) -> float:
|
||||||
"""获取指定群组的回复意愿"""
|
"""获取指定群组的回复意愿"""
|
||||||
@@ -24,45 +29,66 @@ class WillingManager:
|
|||||||
"""设置指定群组的回复意愿"""
|
"""设置指定群组的回复意愿"""
|
||||||
self.group_reply_willing[group_id] = willing
|
self.group_reply_willing[group_id] = willing
|
||||||
|
|
||||||
def change_reply_willing_received(self, group_id: int, topic: str, is_mentioned_bot: bool, config, user_id: int = None, is_emoji: bool = False, interested_rate: float = 0) -> float:
|
def change_reply_willing_received(self, group_id: int, topic: str, is_mentioned_bot: bool, config,
|
||||||
"""改变指定群组的回复意愿并返回回复概率"""
|
user_id: int = None, is_emoji: bool = False, interested_rate: float = 0) -> float:
|
||||||
|
|
||||||
|
# 若非目标回复群组,则直接return
|
||||||
|
if group_id not in config.talk_allowed_groups:
|
||||||
|
reply_probability = 0
|
||||||
|
return reply_probability
|
||||||
|
|
||||||
current_willing = self.group_reply_willing.get(group_id, 0)
|
current_willing = self.group_reply_willing.get(group_id, 0)
|
||||||
|
|
||||||
# print(f"初始意愿: {current_willing}")
|
logger.debug(f"[{group_id}]的初始回复意愿: {current_willing}")
|
||||||
if is_mentioned_bot and current_willing < 1.0:
|
|
||||||
current_willing += 0.9
|
# 根据消息类型(被cue/表情包)调控
|
||||||
logger.info(f"被提及, 当前意愿: {current_willing}")
|
if is_mentioned_bot:
|
||||||
elif is_mentioned_bot:
|
current_willing = min(
|
||||||
current_willing += 0.05
|
3.0,
|
||||||
logger.info(f"被重复提及, 当前意愿: {current_willing}")
|
current_willing + 0.9
|
||||||
|
)
|
||||||
|
logger.debug(f"被提及, 当前意愿: {current_willing}")
|
||||||
|
|
||||||
if is_emoji:
|
if is_emoji:
|
||||||
current_willing *= 0.1
|
current_willing *= 0.1
|
||||||
logger.info(f"表情包, 当前意愿: {current_willing}")
|
logger.debug(f"表情包, 当前意愿: {current_willing}")
|
||||||
|
|
||||||
logger.debug(f"放大系数_interested_rate: {global_config.response_interested_rate_amplifier}")
|
# 兴趣放大系数,若兴趣 > 0.4则增加回复概率
|
||||||
interested_rate *= global_config.response_interested_rate_amplifier #放大回复兴趣度
|
interested_rate_amplifier = global_config.response_interested_rate_amplifier
|
||||||
if interested_rate > 0.4:
|
logger.debug(f"放大系数_interested_rate: {interested_rate_amplifier}")
|
||||||
# print(f"兴趣度: {interested_rate}, 当前意愿: {current_willing}")
|
interested_rate *= interested_rate_amplifier
|
||||||
current_willing += interested_rate-0.4
|
|
||||||
|
|
||||||
current_willing *= global_config.response_willing_amplifier #放大回复意愿
|
current_willing += max(
|
||||||
# print(f"放大系数_willing: {global_config.response_willing_amplifier}, 当前意愿: {current_willing}")
|
0.0,
|
||||||
|
interested_rate - 0.4
|
||||||
|
)
|
||||||
|
|
||||||
reply_probability = max((current_willing - 0.45) * 2, 0)
|
# 回复意愿系数调控,独立乘区
|
||||||
if group_id not in config.talk_allowed_groups:
|
willing_amplifier = max(
|
||||||
current_willing = 0
|
global_config.response_willing_amplifier,
|
||||||
reply_probability = 0
|
self.min_reply_willing
|
||||||
|
)
|
||||||
|
current_willing *= willing_amplifier
|
||||||
|
logger.debug(f"放大系数_willing: {global_config.response_willing_amplifier}, 当前意愿: {current_willing}")
|
||||||
|
|
||||||
|
# 回复概率迭代,保底0.01回复概率
|
||||||
|
reply_probability = max(
|
||||||
|
(current_willing - 0.45) * 2,
|
||||||
|
self.min_reply_willing
|
||||||
|
)
|
||||||
|
|
||||||
|
# 降低目标低频群组回复概率
|
||||||
|
down_frequency_rate = max(
|
||||||
|
1.0,
|
||||||
|
global_config.down_frequency_rate
|
||||||
|
)
|
||||||
if group_id in config.talk_frequency_down_groups:
|
if group_id in config.talk_frequency_down_groups:
|
||||||
reply_probability = reply_probability / global_config.down_frequency_rate
|
reply_probability = reply_probability / down_frequency_rate
|
||||||
|
|
||||||
reply_probability = min(reply_probability, 1)
|
reply_probability = min(reply_probability, 1)
|
||||||
if reply_probability < 0:
|
|
||||||
reply_probability = 0
|
|
||||||
|
|
||||||
|
|
||||||
self.group_reply_willing[group_id] = min(current_willing, 3.0)
|
self.group_reply_willing[group_id] = min(current_willing, 3.0)
|
||||||
|
logger.debug(f"当前群组{group_id}回复概率:{reply_probability}")
|
||||||
return reply_probability
|
return reply_probability
|
||||||
|
|
||||||
def change_reply_willing_sent(self, group_id: int):
|
def change_reply_willing_sent(self, group_id: int):
|
||||||
@@ -83,5 +109,6 @@ class WillingManager:
|
|||||||
self._decay_task = asyncio.create_task(self._decay_reply_willing())
|
self._decay_task = asyncio.create_task(self._decay_reply_willing())
|
||||||
self._started = True
|
self._started = True
|
||||||
|
|
||||||
|
|
||||||
# 创建全局实例
|
# 创建全局实例
|
||||||
willing_manager = WillingManager()
|
willing_manager = WillingManager()
|
||||||
|
|||||||
Reference in New Issue
Block a user