Merge branch 'debug' of https://github.com/SengokuCola/MaiMBot into debug
This commit is contained in:
@@ -7,7 +7,7 @@ from datetime import datetime
|
||||
from typing import Dict, List
|
||||
from loguru import logger
|
||||
from typing import Optional
|
||||
from ..common.database import db
|
||||
|
||||
|
||||
import customtkinter as ctk
|
||||
from dotenv import load_dotenv
|
||||
@@ -16,6 +16,8 @@ from dotenv import load_dotenv
|
||||
current_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
# 获取项目根目录
|
||||
root_dir = os.path.abspath(os.path.join(current_dir, '..', '..'))
|
||||
sys.path.insert(0, root_dir)
|
||||
from src.common.database import db
|
||||
|
||||
# 加载环境变量
|
||||
if os.path.exists(os.path.join(root_dir, '.env.dev')):
|
||||
|
||||
@@ -139,3 +139,12 @@ async def print_mood_task():
|
||||
"""每30秒打印一次情绪状态"""
|
||||
mood_manager = MoodManager.get_instance()
|
||||
mood_manager.print_mood_status()
|
||||
|
||||
|
||||
@scheduler.scheduled_job("interval", seconds=7200, id="generate_schedule")
|
||||
async def generate_schedule_task():
|
||||
"""每2小时尝试生成一次日程"""
|
||||
logger.debug("尝试生成日程")
|
||||
await bot_schedule.initialize()
|
||||
if not bot_schedule.enable_output:
|
||||
bot_schedule.print_schedule()
|
||||
|
||||
@@ -231,6 +231,7 @@ class ChatBot:
|
||||
config=global_config,
|
||||
is_emoji=message.is_emoji,
|
||||
interested_rate=interested_rate,
|
||||
sender_id=str(message.message_info.user_info.user_id),
|
||||
)
|
||||
current_willing = willing_manager.get_willing(chat_stream=chat)
|
||||
|
||||
@@ -261,6 +262,9 @@ class ChatBot:
|
||||
willing_manager.change_reply_willing_sent(chat)
|
||||
|
||||
response, raw_content = await self.gpt.generate_response(message)
|
||||
else:
|
||||
# 决定不回复时,也更新回复意愿
|
||||
willing_manager.change_reply_willing_not_sent(chat)
|
||||
|
||||
# print(f"response: {response}")
|
||||
if response:
|
||||
|
||||
@@ -86,9 +86,12 @@ class CQCode:
|
||||
else:
|
||||
self.translated_segments = Seg(type="text", data="[图片]")
|
||||
elif self.type == "at":
|
||||
user_nickname = get_user_nickname(self.params.get("qq", ""))
|
||||
self.translated_segments = Seg(
|
||||
type="text", data=f"[@{user_nickname or '某人'}]"
|
||||
if self.params.get("qq") == "all":
|
||||
self.translated_segments = Seg(type="text", data="@[全体成员]")
|
||||
else:
|
||||
user_nickname = get_user_nickname(self.params.get("qq", ""))
|
||||
self.translated_segments = Seg(
|
||||
type="text", data=f"[@{user_nickname or '某人'}]"
|
||||
)
|
||||
elif self.type == "reply":
|
||||
reply_segments = self.translate_reply()
|
||||
|
||||
@@ -31,7 +31,7 @@ image_manager = ImageManager()
|
||||
|
||||
class EmojiManager:
|
||||
_instance = None
|
||||
EMOJI_DIR = "data/emoji" # 表情包存储目录
|
||||
EMOJI_DIR = os.path.join("data", "emoji") # 表情包存储目录
|
||||
|
||||
def __new__(cls):
|
||||
if cls._instance is None:
|
||||
@@ -217,7 +217,7 @@ class EmojiManager:
|
||||
async def scan_new_emojis(self):
|
||||
"""扫描新的表情包"""
|
||||
try:
|
||||
emoji_dir = "data/emoji"
|
||||
emoji_dir = self.EMOJI_DIR
|
||||
os.makedirs(emoji_dir, exist_ok=True)
|
||||
|
||||
# 获取所有支持的图片文件
|
||||
|
||||
@@ -44,18 +44,23 @@ class ImageManager:
|
||||
"""确保images集合存在并创建索引"""
|
||||
if "images" not in db.list_collection_names():
|
||||
db.create_collection("images")
|
||||
# 创建索引
|
||||
db.images.create_index([("hash", 1)], unique=True)
|
||||
db.images.create_index([("url", 1)])
|
||||
db.images.create_index([("path", 1)])
|
||||
|
||||
# 删除旧索引
|
||||
db.images.drop_indexes()
|
||||
# 创建新的复合索引
|
||||
db.images.create_index([("hash", 1), ("type", 1)], unique=True)
|
||||
db.images.create_index([("url", 1)])
|
||||
db.images.create_index([("path", 1)])
|
||||
|
||||
def _ensure_description_collection(self):
|
||||
"""确保image_descriptions集合存在并创建索引"""
|
||||
if "image_descriptions" not in db.list_collection_names():
|
||||
db.create_collection("image_descriptions")
|
||||
# 创建索引
|
||||
db.image_descriptions.create_index([("hash", 1)], unique=True)
|
||||
db.image_descriptions.create_index([("type", 1)])
|
||||
|
||||
# 删除旧索引
|
||||
db.image_descriptions.drop_indexes()
|
||||
# 创建新的复合索引
|
||||
db.image_descriptions.create_index([("hash", 1), ("type", 1)], unique=True)
|
||||
|
||||
def _get_description_from_db(self, image_hash: str, description_type: str) -> Optional[str]:
|
||||
"""从数据库获取图片描述
|
||||
@@ -78,36 +83,21 @@ class ImageManager:
|
||||
description: 描述文本
|
||||
description_type: 描述类型 ('emoji' 或 'image')
|
||||
"""
|
||||
db.image_descriptions.update_one(
|
||||
{"hash": image_hash, "type": description_type},
|
||||
{"$set": {"description": description, "timestamp": int(time.time())}},
|
||||
upsert=True,
|
||||
)
|
||||
|
||||
async def get_image_by_url(self, url: str) -> Optional[str]:
|
||||
"""根据URL获取图像路径(带查重)
|
||||
Args:
|
||||
url: 图像URL
|
||||
Returns:
|
||||
str: 本地文件路径,不存在返回None
|
||||
"""
|
||||
try:
|
||||
# 先查找是否已存在
|
||||
existing = db.images.find_one({"url": url})
|
||||
if existing:
|
||||
return existing["path"]
|
||||
|
||||
# 下载图像
|
||||
async with aiohttp.ClientSession() as session:
|
||||
async with session.get(url) as resp:
|
||||
if resp.status == 200:
|
||||
image_bytes = await resp.read()
|
||||
return await self.save_image(image_bytes, url=url)
|
||||
return None
|
||||
|
||||
db.image_descriptions.update_one(
|
||||
{"hash": image_hash, "type": description_type},
|
||||
{
|
||||
"$set": {
|
||||
"description": description,
|
||||
"timestamp": int(time.time()),
|
||||
"hash": image_hash, # 确保hash字段存在
|
||||
"type": description_type, # 确保type字段存在
|
||||
}
|
||||
},
|
||||
upsert=True,
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(f"获取图像失败: {str(e)}")
|
||||
return None
|
||||
logger.error(f"保存描述到数据库失败: {str(e)}")
|
||||
|
||||
async def get_emoji_description(self, image_base64: str) -> str:
|
||||
"""获取表情包描述,带查重和保存功能"""
|
||||
@@ -129,7 +119,7 @@ class ImageManager:
|
||||
|
||||
cached_description = self._get_description_from_db(image_hash, "emoji")
|
||||
if cached_description:
|
||||
logger.warning(f"虽然生成了描述,但找到缓存表情包描述: {cached_description}")
|
||||
logger.warning(f"虽然生成了描述,但是找到缓存表情包描述: {cached_description}")
|
||||
return f"[表情包:{cached_description}]"
|
||||
|
||||
# 根据配置决定是否保存图片
|
||||
@@ -170,7 +160,6 @@ class ImageManager:
|
||||
async def get_image_description(self, image_base64: str) -> str:
|
||||
"""获取普通图片描述,带查重和保存功能"""
|
||||
try:
|
||||
print("处理图片中")
|
||||
# 计算图片哈希
|
||||
image_bytes = base64.b64decode(image_base64)
|
||||
image_hash = hashlib.md5(image_bytes).hexdigest()
|
||||
@@ -179,7 +168,7 @@ class ImageManager:
|
||||
# 查询缓存的描述
|
||||
cached_description = self._get_description_from_db(image_hash, "image")
|
||||
if cached_description:
|
||||
print("图片描述缓存中")
|
||||
logger.info(f"图片描述缓存中 {cached_description}")
|
||||
return f"[图片:{cached_description}]"
|
||||
|
||||
# 调用AI获取描述
|
||||
@@ -187,12 +176,13 @@ class ImageManager:
|
||||
"请用中文描述这张图片的内容。如果有文字,请把文字都描述出来。并尝试猜测这个图片的含义。最多200个字。"
|
||||
)
|
||||
description, _ = await self._llm.generate_response_for_image(prompt, image_base64, image_format)
|
||||
cached_description = self._get_description_from_db(image_hash, "emoji")
|
||||
|
||||
cached_description = self._get_description_from_db(image_hash, "image")
|
||||
if cached_description:
|
||||
logger.info(f"缓存图片描述: {cached_description}")
|
||||
logger.warning(f"虽然生成了描述,但是找到缓存图片描述 {cached_description}")
|
||||
return f"[图片:{cached_description}]"
|
||||
|
||||
print(f"描述是{description}")
|
||||
logger.info(f"描述是{description}")
|
||||
|
||||
if description is None:
|
||||
logger.warning("AI未能生成图片描述")
|
||||
|
||||
@@ -5,14 +5,16 @@ from .relationship_manager import relationship_manager
|
||||
def get_user_nickname(user_id: int) -> str:
|
||||
if int(user_id) == int(global_config.BOT_QQ):
|
||||
return global_config.BOT_NICKNAME
|
||||
# print(user_id)
|
||||
# print(user_id)
|
||||
return relationship_manager.get_name(user_id)
|
||||
|
||||
|
||||
def get_user_cardname(user_id: int) -> str:
|
||||
if int(user_id) == int(global_config.BOT_QQ):
|
||||
return global_config.BOT_NICKNAME
|
||||
# print(user_id)
|
||||
return ''
|
||||
# print(user_id)
|
||||
return ""
|
||||
|
||||
|
||||
def get_groupname(group_id: int) -> str:
|
||||
return f"群{group_id}"
|
||||
return f"群{group_id}"
|
||||
|
||||
@@ -1,109 +1,259 @@
|
||||
import asyncio
|
||||
import random
|
||||
import time
|
||||
from typing import Dict
|
||||
from loguru import logger
|
||||
|
||||
|
||||
from .config import global_config
|
||||
from .chat_stream import ChatStream
|
||||
|
||||
from loguru import logger
|
||||
|
||||
|
||||
class WillingManager:
|
||||
def __init__(self):
|
||||
self.chat_reply_willing: Dict[str, float] = {} # 存储每个聊天流的回复意愿
|
||||
self.chat_high_willing_mode: Dict[str, bool] = {} # 存储每个聊天流是否处于高回复意愿期
|
||||
self.chat_msg_count: Dict[str, int] = {} # 存储每个聊天流接收到的消息数量
|
||||
self.chat_last_mode_change: Dict[str, float] = {} # 存储每个聊天流上次模式切换的时间
|
||||
self.chat_high_willing_duration: Dict[str, int] = {} # 高意愿期持续时间(秒)
|
||||
self.chat_low_willing_duration: Dict[str, int] = {} # 低意愿期持续时间(秒)
|
||||
self.chat_last_reply_time: Dict[str, float] = {} # 存储每个聊天流上次回复的时间
|
||||
self.chat_last_sender_id: Dict[str, str] = {} # 存储每个聊天流上次回复的用户ID
|
||||
self.chat_conversation_context: Dict[str, bool] = {} # 标记是否处于对话上下文中
|
||||
self._decay_task = None
|
||||
self._mode_switch_task = None
|
||||
self._started = False
|
||||
|
||||
|
||||
async def _decay_reply_willing(self):
|
||||
"""定期衰减回复意愿"""
|
||||
while True:
|
||||
await asyncio.sleep(5)
|
||||
for chat_id in self.chat_reply_willing:
|
||||
self.chat_reply_willing[chat_id] = max(0, self.chat_reply_willing[chat_id] * 0.6)
|
||||
|
||||
is_high_mode = self.chat_high_willing_mode.get(chat_id, False)
|
||||
if is_high_mode:
|
||||
# 高回复意愿期内轻微衰减
|
||||
self.chat_reply_willing[chat_id] = max(0.5, self.chat_reply_willing[chat_id] * 0.95)
|
||||
else:
|
||||
# 低回复意愿期内正常衰减
|
||||
self.chat_reply_willing[chat_id] = max(0, self.chat_reply_willing[chat_id] * 0.8)
|
||||
|
||||
async def _mode_switch_check(self):
|
||||
"""定期检查是否需要切换回复意愿模式"""
|
||||
while True:
|
||||
current_time = time.time()
|
||||
await asyncio.sleep(10) # 每10秒检查一次
|
||||
|
||||
for chat_id in self.chat_high_willing_mode:
|
||||
last_change_time = self.chat_last_mode_change.get(chat_id, 0)
|
||||
is_high_mode = self.chat_high_willing_mode.get(chat_id, False)
|
||||
|
||||
# 获取当前模式的持续时间
|
||||
duration = 0
|
||||
if is_high_mode:
|
||||
duration = self.chat_high_willing_duration.get(chat_id, 180) # 默认3分钟
|
||||
else:
|
||||
duration = self.chat_low_willing_duration.get(chat_id, random.randint(300, 1200)) # 默认5-20分钟
|
||||
|
||||
# 检查是否需要切换模式
|
||||
if current_time - last_change_time > duration:
|
||||
self._switch_willing_mode(chat_id)
|
||||
elif not is_high_mode and random.random() < 0.1:
|
||||
# 低回复意愿期有10%概率随机切换到高回复期
|
||||
self._switch_willing_mode(chat_id)
|
||||
|
||||
# 检查对话上下文状态是否需要重置
|
||||
last_reply_time = self.chat_last_reply_time.get(chat_id, 0)
|
||||
if current_time - last_reply_time > 300: # 5分钟无交互,重置对话上下文
|
||||
self.chat_conversation_context[chat_id] = False
|
||||
|
||||
def _switch_willing_mode(self, chat_id: str):
|
||||
"""切换聊天流的回复意愿模式"""
|
||||
is_high_mode = self.chat_high_willing_mode.get(chat_id, False)
|
||||
|
||||
if is_high_mode:
|
||||
# 从高回复期切换到低回复期
|
||||
self.chat_high_willing_mode[chat_id] = False
|
||||
self.chat_reply_willing[chat_id] = 0.1 # 设置为最低回复意愿
|
||||
self.chat_low_willing_duration[chat_id] = random.randint(600, 1200) # 10-20分钟
|
||||
logger.debug(f"聊天流 {chat_id} 切换到低回复意愿期,持续 {self.chat_low_willing_duration[chat_id]} 秒")
|
||||
else:
|
||||
# 从低回复期切换到高回复期
|
||||
self.chat_high_willing_mode[chat_id] = True
|
||||
self.chat_reply_willing[chat_id] = 1.0 # 设置为较高回复意愿
|
||||
self.chat_high_willing_duration[chat_id] = random.randint(180, 240) # 3-4分钟
|
||||
logger.debug(f"聊天流 {chat_id} 切换到高回复意愿期,持续 {self.chat_high_willing_duration[chat_id]} 秒")
|
||||
|
||||
self.chat_last_mode_change[chat_id] = time.time()
|
||||
self.chat_msg_count[chat_id] = 0 # 重置消息计数
|
||||
|
||||
def get_willing(self, chat_stream: ChatStream) -> float:
|
||||
"""获取指定聊天流的回复意愿"""
|
||||
stream = chat_stream
|
||||
if stream:
|
||||
return self.chat_reply_willing.get(stream.stream_id, 0)
|
||||
return 0
|
||||
|
||||
|
||||
def set_willing(self, chat_id: str, willing: float):
|
||||
"""设置指定聊天流的回复意愿"""
|
||||
self.chat_reply_willing[chat_id] = willing
|
||||
|
||||
async def change_reply_willing_received(
|
||||
self,
|
||||
chat_stream: ChatStream,
|
||||
topic: str = None,
|
||||
is_mentioned_bot: bool = False,
|
||||
config=None,
|
||||
is_emoji: bool = False,
|
||||
interested_rate: float = 0,
|
||||
) -> float:
|
||||
|
||||
def _ensure_chat_initialized(self, chat_id: str):
|
||||
"""确保聊天流的所有数据已初始化"""
|
||||
if chat_id not in self.chat_reply_willing:
|
||||
self.chat_reply_willing[chat_id] = 0.1
|
||||
|
||||
if chat_id not in self.chat_high_willing_mode:
|
||||
self.chat_high_willing_mode[chat_id] = False
|
||||
self.chat_last_mode_change[chat_id] = time.time()
|
||||
self.chat_low_willing_duration[chat_id] = random.randint(300, 1200) # 5-20分钟
|
||||
|
||||
if chat_id not in self.chat_msg_count:
|
||||
self.chat_msg_count[chat_id] = 0
|
||||
|
||||
if chat_id not in self.chat_conversation_context:
|
||||
self.chat_conversation_context[chat_id] = False
|
||||
|
||||
async def change_reply_willing_received(self,
|
||||
chat_stream: ChatStream,
|
||||
topic: str = None,
|
||||
is_mentioned_bot: bool = False,
|
||||
config = None,
|
||||
is_emoji: bool = False,
|
||||
interested_rate: float = 0,
|
||||
sender_id: str = None) -> float:
|
||||
"""改变指定聊天流的回复意愿并返回回复概率"""
|
||||
# 获取或创建聊天流
|
||||
stream = chat_stream
|
||||
chat_id = stream.stream_id
|
||||
|
||||
current_time = time.time()
|
||||
|
||||
self._ensure_chat_initialized(chat_id)
|
||||
|
||||
# 增加消息计数
|
||||
self.chat_msg_count[chat_id] = self.chat_msg_count.get(chat_id, 0) + 1
|
||||
|
||||
current_willing = self.chat_reply_willing.get(chat_id, 0)
|
||||
|
||||
if is_mentioned_bot and current_willing < 1.0:
|
||||
current_willing += 0.9
|
||||
is_high_mode = self.chat_high_willing_mode.get(chat_id, False)
|
||||
msg_count = self.chat_msg_count.get(chat_id, 0)
|
||||
in_conversation_context = self.chat_conversation_context.get(chat_id, False)
|
||||
|
||||
# 检查是否是对话上下文中的追问
|
||||
last_reply_time = self.chat_last_reply_time.get(chat_id, 0)
|
||||
last_sender = self.chat_last_sender_id.get(chat_id, "")
|
||||
is_follow_up_question = False
|
||||
|
||||
# 如果是同一个人在短时间内(2分钟内)发送消息,且消息数量较少(<=5条),视为追问
|
||||
if sender_id and sender_id == last_sender and current_time - last_reply_time < 120 and msg_count <= 5:
|
||||
is_follow_up_question = True
|
||||
in_conversation_context = True
|
||||
self.chat_conversation_context[chat_id] = True
|
||||
logger.debug(f"检测到追问 (同一用户), 提高回复意愿")
|
||||
current_willing += 0.3
|
||||
|
||||
# 特殊情况处理
|
||||
if is_mentioned_bot:
|
||||
current_willing += 0.5
|
||||
in_conversation_context = True
|
||||
self.chat_conversation_context[chat_id] = True
|
||||
logger.debug(f"被提及, 当前意愿: {current_willing}")
|
||||
elif is_mentioned_bot:
|
||||
current_willing += 0.05
|
||||
logger.debug(f"被重复提及, 当前意愿: {current_willing}")
|
||||
|
||||
|
||||
if is_emoji:
|
||||
current_willing *= 0.1
|
||||
logger.debug(f"表情包, 当前意愿: {current_willing}")
|
||||
|
||||
logger.debug(f"放大系数_interested_rate: {global_config.response_interested_rate_amplifier}")
|
||||
interested_rate *= global_config.response_interested_rate_amplifier # 放大回复兴趣度
|
||||
if interested_rate > 0.4:
|
||||
# print(f"兴趣度: {interested_rate}, 当前意愿: {current_willing}")
|
||||
current_willing += interested_rate - 0.4
|
||||
|
||||
current_willing *= global_config.response_willing_amplifier # 放大回复意愿
|
||||
# print(f"放大系数_willing: {global_config.response_willing_amplifier}, 当前意愿: {current_willing}")
|
||||
|
||||
reply_probability = max((current_willing - 0.45) * 2, 0)
|
||||
|
||||
|
||||
# 根据话题兴趣度适当调整
|
||||
if interested_rate > 0.5:
|
||||
current_willing += (interested_rate - 0.5) * 0.5
|
||||
|
||||
# 根据当前模式计算回复概率
|
||||
base_probability = 0.0
|
||||
|
||||
if in_conversation_context:
|
||||
# 在对话上下文中,降低基础回复概率
|
||||
base_probability = 0.5 if is_high_mode else 0.25
|
||||
logger.debug(f"处于对话上下文中,基础回复概率: {base_probability}")
|
||||
elif is_high_mode:
|
||||
# 高回复周期:4-8句话有50%的概率会回复一次
|
||||
base_probability = 0.50 if 4 <= msg_count <= 8 else 0.2
|
||||
else:
|
||||
# 低回复周期:需要最少15句才有30%的概率会回一句
|
||||
base_probability = 0.30 if msg_count >= 15 else 0.03 * min(msg_count, 10)
|
||||
|
||||
# 考虑回复意愿的影响
|
||||
reply_probability = base_probability * current_willing
|
||||
|
||||
# 检查群组权限(如果是群聊)
|
||||
if chat_stream.group_info:
|
||||
if chat_stream.group_info and config:
|
||||
if chat_stream.group_info.group_id in config.talk_frequency_down_groups:
|
||||
reply_probability = reply_probability / global_config.down_frequency_rate
|
||||
|
||||
reply_probability = min(reply_probability, 1)
|
||||
# 限制最大回复概率
|
||||
reply_probability = min(reply_probability, 0.75) # 设置最大回复概率为75%
|
||||
if reply_probability < 0:
|
||||
reply_probability = 0
|
||||
|
||||
|
||||
# 记录当前发送者ID以便后续追踪
|
||||
if sender_id:
|
||||
self.chat_last_sender_id[chat_id] = sender_id
|
||||
|
||||
self.chat_reply_willing[chat_id] = min(current_willing, 3.0)
|
||||
return reply_probability
|
||||
|
||||
|
||||
def change_reply_willing_sent(self, chat_stream: ChatStream):
|
||||
"""开始思考后降低聊天流的回复意愿"""
|
||||
stream = chat_stream
|
||||
if stream:
|
||||
current_willing = self.chat_reply_willing.get(stream.stream_id, 0)
|
||||
self.chat_reply_willing[stream.stream_id] = max(0, current_willing - 2)
|
||||
|
||||
def change_reply_willing_after_sent(self, chat_stream: ChatStream):
|
||||
"""发送消息后提高聊天流的回复意愿"""
|
||||
chat_id = stream.stream_id
|
||||
self._ensure_chat_initialized(chat_id)
|
||||
is_high_mode = self.chat_high_willing_mode.get(chat_id, False)
|
||||
current_willing = self.chat_reply_willing.get(chat_id, 0)
|
||||
|
||||
# 回复后减少回复意愿
|
||||
self.chat_reply_willing[chat_id] = max(0, current_willing - 0.3)
|
||||
|
||||
# 标记为对话上下文中
|
||||
self.chat_conversation_context[chat_id] = True
|
||||
|
||||
# 记录最后回复时间
|
||||
self.chat_last_reply_time[chat_id] = time.time()
|
||||
|
||||
# 重置消息计数
|
||||
self.chat_msg_count[chat_id] = 0
|
||||
|
||||
def change_reply_willing_not_sent(self, chat_stream: ChatStream):
|
||||
"""决定不回复后提高聊天流的回复意愿"""
|
||||
stream = chat_stream
|
||||
if stream:
|
||||
current_willing = self.chat_reply_willing.get(stream.stream_id, 0)
|
||||
if current_willing < 1:
|
||||
self.chat_reply_willing[stream.stream_id] = min(1, current_willing + 0.2)
|
||||
|
||||
chat_id = stream.stream_id
|
||||
self._ensure_chat_initialized(chat_id)
|
||||
is_high_mode = self.chat_high_willing_mode.get(chat_id, False)
|
||||
current_willing = self.chat_reply_willing.get(chat_id, 0)
|
||||
in_conversation_context = self.chat_conversation_context.get(chat_id, False)
|
||||
|
||||
# 根据当前模式调整不回复后的意愿增加
|
||||
if is_high_mode:
|
||||
willing_increase = 0.1
|
||||
elif in_conversation_context:
|
||||
# 在对话上下文中但决定不回复,小幅增加回复意愿
|
||||
willing_increase = 0.15
|
||||
else:
|
||||
willing_increase = random.uniform(0.05, 0.1)
|
||||
|
||||
self.chat_reply_willing[chat_id] = min(2.0, current_willing + willing_increase)
|
||||
|
||||
def change_reply_willing_after_sent(self, chat_stream: ChatStream):
|
||||
"""发送消息后提高聊天流的回复意愿"""
|
||||
# 由于已经在sent中处理,这个方法保留但不再需要额外调整
|
||||
pass
|
||||
|
||||
async def ensure_started(self):
|
||||
"""确保衰减任务已启动"""
|
||||
"""确保所有任务已启动"""
|
||||
if not self._started:
|
||||
if self._decay_task is None:
|
||||
self._decay_task = asyncio.create_task(self._decay_reply_willing())
|
||||
if self._mode_switch_task is None:
|
||||
self._mode_switch_task = asyncio.create_task(self._mode_switch_check())
|
||||
self._started = True
|
||||
|
||||
|
||||
# 创建全局实例
|
||||
willing_manager = WillingManager()
|
||||
willing_manager = WillingManager()
|
||||
@@ -14,7 +14,10 @@ from ..models.utils_model import LLM_request
|
||||
driver = get_driver()
|
||||
config = driver.config
|
||||
|
||||
|
||||
class ScheduleGenerator:
|
||||
enable_output: bool = True
|
||||
|
||||
def __init__(self):
|
||||
# 根据global_config.llm_normal这一字典配置指定模型
|
||||
# self.llm_scheduler = LLMModel(model = global_config.llm_normal,temperature=0.9)
|
||||
@@ -32,14 +35,16 @@ class ScheduleGenerator:
|
||||
yesterday = datetime.datetime.now() - datetime.timedelta(days=1)
|
||||
|
||||
self.today_schedule_text, self.today_schedule = await self.generate_daily_schedule(target_date=today)
|
||||
self.tomorrow_schedule_text, self.tomorrow_schedule = await self.generate_daily_schedule(target_date=tomorrow,
|
||||
read_only=True)
|
||||
self.tomorrow_schedule_text, self.tomorrow_schedule = await self.generate_daily_schedule(
|
||||
target_date=tomorrow, read_only=True
|
||||
)
|
||||
self.yesterday_schedule_text, self.yesterday_schedule = await self.generate_daily_schedule(
|
||||
target_date=yesterday, read_only=True)
|
||||
|
||||
async def generate_daily_schedule(self, target_date: datetime.datetime = None, read_only: bool = False) -> Dict[
|
||||
str, str]:
|
||||
target_date=yesterday, read_only=True
|
||||
)
|
||||
|
||||
async def generate_daily_schedule(
|
||||
self, target_date: datetime.datetime = None, read_only: bool = False
|
||||
) -> Dict[str, str]:
|
||||
date_str = target_date.strftime("%Y-%m-%d")
|
||||
weekday = target_date.strftime("%A")
|
||||
|
||||
@@ -47,28 +52,33 @@ class ScheduleGenerator:
|
||||
|
||||
existing_schedule = db.schedule.find_one({"date": date_str})
|
||||
if existing_schedule:
|
||||
logger.debug(f"{date_str}的日程已存在:")
|
||||
if self.enable_output:
|
||||
logger.debug(f"{date_str}的日程已存在:")
|
||||
schedule_text = existing_schedule["schedule"]
|
||||
# print(self.schedule_text)
|
||||
|
||||
elif not read_only:
|
||||
logger.debug(f"{date_str}的日程不存在,准备生成新的日程。")
|
||||
prompt = f"""我是{global_config.BOT_NICKNAME},{global_config.PROMPT_SCHEDULE_GEN},请为我生成{date_str}({weekday})的日程安排,包括:""" + \
|
||||
"""
|
||||
prompt = (
|
||||
f"""我是{global_config.BOT_NICKNAME},{global_config.PROMPT_SCHEDULE_GEN},请为我生成{date_str}({weekday})的日程安排,包括:"""
|
||||
+ """
|
||||
1. 早上的学习和工作安排
|
||||
2. 下午的活动和任务
|
||||
3. 晚上的计划和休息时间
|
||||
请按照时间顺序列出具体时间点和对应的活动,用一个时间点而不是时间段来表示时间,用JSON格式返回日程表,仅返回内容,不要返回注释,不要添加任何markdown或代码块样式,时间采用24小时制,格式为{"时间": "活动","时间": "活动",...}。"""
|
||||
)
|
||||
|
||||
try:
|
||||
schedule_text, _ = await self.llm_scheduler.generate_response(prompt)
|
||||
db.schedule.insert_one({"date": date_str, "schedule": schedule_text})
|
||||
self.enable_output = True
|
||||
except Exception as e:
|
||||
logger.error(f"生成日程失败: {str(e)}")
|
||||
schedule_text = "生成日程时出错了"
|
||||
# print(self.schedule_text)
|
||||
else:
|
||||
logger.debug(f"{date_str}的日程不存在。")
|
||||
if self.enable_output:
|
||||
logger.debug(f"{date_str}的日程不存在。")
|
||||
schedule_text = "忘了"
|
||||
|
||||
return schedule_text, None
|
||||
@@ -95,7 +105,7 @@ class ScheduleGenerator:
|
||||
|
||||
# 找到最接近当前时间的任务
|
||||
closest_time = None
|
||||
min_diff = float('inf')
|
||||
min_diff = float("inf")
|
||||
|
||||
# 检查今天的日程
|
||||
if not self.today_schedule:
|
||||
@@ -148,6 +158,7 @@ class ScheduleGenerator:
|
||||
for time_str, activity in self.today_schedule.items():
|
||||
logger.info(f"时间[{time_str}]: 活动[{activity}]")
|
||||
logger.info("==================")
|
||||
self.enable_output = False
|
||||
|
||||
|
||||
# def main():
|
||||
|
||||
Reference in New Issue
Block a user