mirror of https://github.com/Mai-with-u/MaiBot.git
remove:移除情绪功能
parent
d7cf57f48e
commit
eb86d3ed43
|
|
@ -7,7 +7,6 @@ from maim_message import UserInfo, Seg, GroupInfo
|
||||||
|
|
||||||
from src.common.logger import get_logger
|
from src.common.logger import get_logger
|
||||||
from src.config.config import global_config
|
from src.config.config import global_config
|
||||||
from src.mood.mood_manager import mood_manager # 导入情绪管理器
|
|
||||||
from src.chat.message_receive.chat_stream import get_chat_manager
|
from src.chat.message_receive.chat_stream import get_chat_manager
|
||||||
from src.chat.message_receive.message import MessageRecv
|
from src.chat.message_receive.message import MessageRecv
|
||||||
from src.chat.message_receive.storage import MessageStorage
|
from src.chat.message_receive.storage import MessageStorage
|
||||||
|
|
@ -73,7 +72,6 @@ class ChatBot:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.bot = None # bot 实例引用
|
self.bot = None # bot 实例引用
|
||||||
self._started = False
|
self._started = False
|
||||||
self.mood_manager = mood_manager # 获取情绪管理器单例
|
|
||||||
self.heartflow_message_receiver = HeartFCMessageReceiver() # 新增
|
self.heartflow_message_receiver = HeartFCMessageReceiver() # 新增
|
||||||
|
|
||||||
async def _ensure_started(self):
|
async def _ensure_started(self):
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@ from src.chat.message_receive.uni_message_sender import UniversalMessageSender
|
||||||
from src.chat.utils.timer_calculator import Timer # <--- Import Timer
|
from src.chat.utils.timer_calculator import Timer # <--- Import Timer
|
||||||
from src.chat.utils.utils import get_chat_type_and_target_info
|
from src.chat.utils.utils import get_chat_type_and_target_info
|
||||||
from src.chat.utils.prompt_builder import global_prompt_manager
|
from src.chat.utils.prompt_builder import global_prompt_manager
|
||||||
from src.mood.mood_manager import mood_manager
|
|
||||||
from src.chat.utils.chat_message_builder import (
|
from src.chat.utils.chat_message_builder import (
|
||||||
build_readable_messages,
|
build_readable_messages,
|
||||||
get_raw_msg_before_timestamp_with_chat,
|
get_raw_msg_before_timestamp_with_chat,
|
||||||
|
|
@ -272,12 +271,6 @@ class DefaultReplyer:
|
||||||
|
|
||||||
return f"{expression_habits_title}\n{expression_habits_block}", selected_ids
|
return f"{expression_habits_title}\n{expression_habits_block}", selected_ids
|
||||||
|
|
||||||
async def build_mood_state_prompt(self) -> str:
|
|
||||||
"""构建情绪状态提示"""
|
|
||||||
if not global_config.mood.enable_mood:
|
|
||||||
return ""
|
|
||||||
mood_state = await mood_manager.get_mood_by_chat_id(self.chat_stream.stream_id).get_mood()
|
|
||||||
return f"你现在的心情是:{mood_state}"
|
|
||||||
|
|
||||||
async def build_tool_info(self, chat_history: str, sender: str, target: str, enable_tool: bool = True) -> str:
|
async def build_tool_info(self, chat_history: str, sender: str, target: str, enable_tool: bool = True) -> str:
|
||||||
"""构建工具信息块
|
"""构建工具信息块
|
||||||
|
|
@ -800,7 +793,6 @@ class DefaultReplyer:
|
||||||
self._time_and_run_task(self.get_prompt_info(chat_talking_prompt_short, sender, target), "prompt_info"),
|
self._time_and_run_task(self.get_prompt_info(chat_talking_prompt_short, sender, target), "prompt_info"),
|
||||||
self._time_and_run_task(self.build_actions_prompt(available_actions, chosen_actions), "actions_info"),
|
self._time_and_run_task(self.build_actions_prompt(available_actions, chosen_actions), "actions_info"),
|
||||||
self._time_and_run_task(self.build_personality_prompt(), "personality_prompt"),
|
self._time_and_run_task(self.build_personality_prompt(), "personality_prompt"),
|
||||||
self._time_and_run_task(self.build_mood_state_prompt(), "mood_state_prompt"),
|
|
||||||
self._time_and_run_task(
|
self._time_and_run_task(
|
||||||
build_memory_retrieval_prompt(
|
build_memory_retrieval_prompt(
|
||||||
chat_talking_prompt_short, sender, target, self.chat_stream, self.tool_executor
|
chat_talking_prompt_short, sender, target, self.chat_stream, self.tool_executor
|
||||||
|
|
@ -821,7 +813,6 @@ class DefaultReplyer:
|
||||||
"prompt_info": "获取知识",
|
"prompt_info": "获取知识",
|
||||||
"actions_info": "动作信息",
|
"actions_info": "动作信息",
|
||||||
"personality_prompt": "人格信息",
|
"personality_prompt": "人格信息",
|
||||||
"mood_state_prompt": "情绪状态",
|
|
||||||
"memory_retrieval": "记忆检索",
|
"memory_retrieval": "记忆检索",
|
||||||
"jargon_explanation": "黑话解释",
|
"jargon_explanation": "黑话解释",
|
||||||
}
|
}
|
||||||
|
|
@ -851,7 +842,6 @@ class DefaultReplyer:
|
||||||
personality_prompt: str = results_dict["personality_prompt"]
|
personality_prompt: str = results_dict["personality_prompt"]
|
||||||
memory_retrieval: str = results_dict["memory_retrieval"]
|
memory_retrieval: str = results_dict["memory_retrieval"]
|
||||||
keywords_reaction_prompt = await self.build_keywords_reaction_prompt(target)
|
keywords_reaction_prompt = await self.build_keywords_reaction_prompt(target)
|
||||||
mood_state_prompt: str = results_dict["mood_state_prompt"]
|
|
||||||
jargon_explanation: str = results_dict.get("jargon_explanation") or ""
|
jargon_explanation: str = results_dict.get("jargon_explanation") or ""
|
||||||
|
|
||||||
# 从 chosen_actions 中提取 planner 的整体思考理由
|
# 从 chosen_actions 中提取 planner 的整体思考理由
|
||||||
|
|
@ -900,7 +890,6 @@ class DefaultReplyer:
|
||||||
tool_info_block=tool_info,
|
tool_info_block=tool_info,
|
||||||
bot_name=global_config.bot.nickname,
|
bot_name=global_config.bot.nickname,
|
||||||
knowledge_prompt=prompt_info,
|
knowledge_prompt=prompt_info,
|
||||||
mood_state=mood_state_prompt,
|
|
||||||
# relation_info_block=relation_info,
|
# relation_info_block=relation_info,
|
||||||
extra_info_block=extra_info_block,
|
extra_info_block=extra_info_block,
|
||||||
jargon_explanation=jargon_explanation,
|
jargon_explanation=jargon_explanation,
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,6 @@ from src.chat.utils.chat_message_builder import (
|
||||||
)
|
)
|
||||||
from src.express.expression_selector import expression_selector
|
from src.express.expression_selector import expression_selector
|
||||||
from src.plugin_system.apis.message_api import translate_pid_to_description
|
from src.plugin_system.apis.message_api import translate_pid_to_description
|
||||||
from src.mood.mood_manager import mood_manager
|
|
||||||
|
|
||||||
# from src.memory_system.memory_activator import MemoryActivator
|
# from src.memory_system.memory_activator import MemoryActivator
|
||||||
|
|
||||||
|
|
@ -287,12 +286,6 @@ class PrivateReplyer:
|
||||||
|
|
||||||
return f"{expression_habits_title}\n{expression_habits_block}", selected_ids
|
return f"{expression_habits_title}\n{expression_habits_block}", selected_ids
|
||||||
|
|
||||||
async def build_mood_state_prompt(self) -> str:
|
|
||||||
"""构建情绪状态提示"""
|
|
||||||
if not global_config.mood.enable_mood:
|
|
||||||
return ""
|
|
||||||
mood_state = await mood_manager.get_mood_by_chat_id(self.chat_stream.stream_id).get_mood()
|
|
||||||
return f"你现在的心情是:{mood_state}"
|
|
||||||
|
|
||||||
async def build_tool_info(self, chat_history: str, sender: str, target: str, enable_tool: bool = True) -> str:
|
async def build_tool_info(self, chat_history: str, sender: str, target: str, enable_tool: bool = True) -> str:
|
||||||
"""构建工具信息块
|
"""构建工具信息块
|
||||||
|
|
@ -721,7 +714,6 @@ class PrivateReplyer:
|
||||||
self._time_and_run_task(self.get_prompt_info(chat_talking_prompt_short, sender, target), "prompt_info"),
|
self._time_and_run_task(self.get_prompt_info(chat_talking_prompt_short, sender, target), "prompt_info"),
|
||||||
self._time_and_run_task(self.build_actions_prompt(available_actions, chosen_actions), "actions_info"),
|
self._time_and_run_task(self.build_actions_prompt(available_actions, chosen_actions), "actions_info"),
|
||||||
self._time_and_run_task(self.build_personality_prompt(), "personality_prompt"),
|
self._time_and_run_task(self.build_personality_prompt(), "personality_prompt"),
|
||||||
self._time_and_run_task(self.build_mood_state_prompt(), "mood_state_prompt"),
|
|
||||||
self._time_and_run_task(
|
self._time_and_run_task(
|
||||||
build_memory_retrieval_prompt(
|
build_memory_retrieval_prompt(
|
||||||
chat_talking_prompt_short, sender, target, self.chat_stream, self.tool_executor
|
chat_talking_prompt_short, sender, target, self.chat_stream, self.tool_executor
|
||||||
|
|
@ -742,7 +734,6 @@ class PrivateReplyer:
|
||||||
"prompt_info": "获取知识",
|
"prompt_info": "获取知识",
|
||||||
"actions_info": "动作信息",
|
"actions_info": "动作信息",
|
||||||
"personality_prompt": "人格信息",
|
"personality_prompt": "人格信息",
|
||||||
"mood_state_prompt": "情绪状态",
|
|
||||||
"memory_retrieval": "记忆检索",
|
"memory_retrieval": "记忆检索",
|
||||||
"jargon_explanation": "黑话解释",
|
"jargon_explanation": "黑话解释",
|
||||||
}
|
}
|
||||||
|
|
@ -770,7 +761,6 @@ class PrivateReplyer:
|
||||||
prompt_info: str = results_dict["prompt_info"] # 直接使用格式化后的结果
|
prompt_info: str = results_dict["prompt_info"] # 直接使用格式化后的结果
|
||||||
actions_info: str = results_dict["actions_info"]
|
actions_info: str = results_dict["actions_info"]
|
||||||
personality_prompt: str = results_dict["personality_prompt"]
|
personality_prompt: str = results_dict["personality_prompt"]
|
||||||
mood_state_prompt: str = results_dict["mood_state_prompt"]
|
|
||||||
memory_retrieval: str = results_dict["memory_retrieval"]
|
memory_retrieval: str = results_dict["memory_retrieval"]
|
||||||
keywords_reaction_prompt = await self.build_keywords_reaction_prompt(target)
|
keywords_reaction_prompt = await self.build_keywords_reaction_prompt(target)
|
||||||
jargon_explanation: str = results_dict.get("jargon_explanation") or ""
|
jargon_explanation: str = results_dict.get("jargon_explanation") or ""
|
||||||
|
|
@ -814,7 +804,6 @@ class PrivateReplyer:
|
||||||
expression_habits_block=expression_habits_block,
|
expression_habits_block=expression_habits_block,
|
||||||
tool_info_block=tool_info,
|
tool_info_block=tool_info,
|
||||||
knowledge_prompt=prompt_info,
|
knowledge_prompt=prompt_info,
|
||||||
mood_state=mood_state_prompt,
|
|
||||||
relation_info_block=relation_info,
|
relation_info_block=relation_info,
|
||||||
extra_info_block=extra_info_block,
|
extra_info_block=extra_info_block,
|
||||||
identity=personality_prompt,
|
identity=personality_prompt,
|
||||||
|
|
@ -837,7 +826,6 @@ class PrivateReplyer:
|
||||||
expression_habits_block=expression_habits_block,
|
expression_habits_block=expression_habits_block,
|
||||||
tool_info_block=tool_info,
|
tool_info_block=tool_info,
|
||||||
knowledge_prompt=prompt_info,
|
knowledge_prompt=prompt_info,
|
||||||
mood_state=mood_state_prompt,
|
|
||||||
relation_info_block=relation_info,
|
relation_info_block=relation_info,
|
||||||
extra_info_block=extra_info_block,
|
extra_info_block=extra_info_block,
|
||||||
identity=personality_prompt,
|
identity=personality_prompt,
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ def init_replyer_prompt():
|
||||||
{reply_target_block}。
|
{reply_target_block}。
|
||||||
{planner_reasoning}
|
{planner_reasoning}
|
||||||
{identity}
|
{identity}
|
||||||
{chat_prompt}你正在群里聊天,现在请你读读之前的聊天记录,然后给出日常且口语化的回复,平淡一些,{mood_state}
|
{chat_prompt}你正在群里聊天,现在请你读读之前的聊天记录,然后给出日常且口语化的回复,平淡一些,
|
||||||
尽量简短一些。{keywords_reaction_prompt}请注意把握聊天内容,不要回复的太有条理。
|
尽量简短一些。{keywords_reaction_prompt}请注意把握聊天内容,不要回复的太有条理。
|
||||||
{reply_style}
|
{reply_style}
|
||||||
请注意不要输出多余内容(包括前后缀,冒号和引号,括号,表情等),只输出一句回复内容就好。
|
请注意不要输出多余内容(包括前后缀,冒号和引号,括号,表情等),只输出一句回复内容就好。
|
||||||
|
|
@ -38,7 +38,7 @@ def init_replyer_prompt():
|
||||||
{reply_target_block}。
|
{reply_target_block}。
|
||||||
{planner_reasoning}
|
{planner_reasoning}
|
||||||
{identity}
|
{identity}
|
||||||
{chat_prompt}你正在和{sender_name}聊天,现在请你读读之前的聊天记录,然后给出日常且口语化的回复,平淡一些,{mood_state}
|
{chat_prompt}你正在和{sender_name}聊天,现在请你读读之前的聊天记录,然后给出日常且口语化的回复,平淡一些,
|
||||||
尽量简短一些。{keywords_reaction_prompt}请注意把握聊天内容,不要回复的太有条理。
|
尽量简短一些。{keywords_reaction_prompt}请注意把握聊天内容,不要回复的太有条理。
|
||||||
{reply_style}
|
{reply_style}
|
||||||
请注意不要输出多余内容(包括前后缀,冒号和引号,括号,表情等),只输出回复内容。
|
请注意不要输出多余内容(包括前后缀,冒号和引号,括号,表情等),只输出回复内容。
|
||||||
|
|
@ -55,7 +55,7 @@ def init_replyer_prompt():
|
||||||
{dialogue_prompt}
|
{dialogue_prompt}
|
||||||
|
|
||||||
你现在想补充说明你刚刚自己的发言内容:{target},原因是{reason}
|
你现在想补充说明你刚刚自己的发言内容:{target},原因是{reason}
|
||||||
请你根据聊天内容,组织一条新回复。注意,{target} 是刚刚你自己的发言,你要在这基础上进一步发言,请按照你自己的角度来继续进行回复。注意保持上下文的连贯性。{mood_state}
|
请你根据聊天内容,组织一条新回复。注意,{target} 是刚刚你自己的发言,你要在这基础上进一步发言,请按照你自己的角度来继续进行回复。注意保持上下文的连贯性。
|
||||||
{identity}
|
{identity}
|
||||||
{chat_prompt}尽量简短一些。{keywords_reaction_prompt}请注意把握聊天内容,不要回复的太有条理,可以有个性。
|
{chat_prompt}尽量简短一些。{keywords_reaction_prompt}请注意把握聊天内容,不要回复的太有条理,可以有个性。
|
||||||
{reply_style}
|
{reply_style}
|
||||||
|
|
|
||||||
|
|
@ -592,22 +592,41 @@ def _fix_table_constraints(table_name, model, constraints_to_fix):
|
||||||
db.execute_sql(f"CREATE TABLE {backup_table} AS SELECT * FROM {table_name}")
|
db.execute_sql(f"CREATE TABLE {backup_table} AS SELECT * FROM {table_name}")
|
||||||
logger.info(f"已创建备份表 '{backup_table}'")
|
logger.info(f"已创建备份表 '{backup_table}'")
|
||||||
|
|
||||||
# 2. 删除原表
|
# 2. 获取原始行数(在删除表之前)
|
||||||
|
original_count = db.execute_sql(f"SELECT COUNT(*) FROM {backup_table}").fetchone()[0]
|
||||||
|
logger.info(f"备份表 '{backup_table}' 包含 {original_count} 行数据")
|
||||||
|
|
||||||
|
# 3. 删除原表
|
||||||
db.execute_sql(f"DROP TABLE {table_name}")
|
db.execute_sql(f"DROP TABLE {table_name}")
|
||||||
logger.info(f"已删除原表 '{table_name}'")
|
logger.info(f"已删除原表 '{table_name}'")
|
||||||
|
|
||||||
# 3. 重新创建表(使用当前模型定义)
|
# 4. 重新创建表(使用当前模型定义)
|
||||||
db.create_tables([model])
|
db.create_tables([model])
|
||||||
logger.info(f"已重新创建表 '{table_name}' 使用新的约束")
|
logger.info(f"已重新创建表 '{table_name}' 使用新的约束")
|
||||||
|
|
||||||
# 4. 从备份表恢复数据
|
# 5. 从备份表恢复数据
|
||||||
# 获取字段列表
|
# 获取字段列表,排除主键字段(让数据库自动生成新的主键)
|
||||||
fields = list(model._meta.fields.keys())
|
fields = list(model._meta.fields.keys())
|
||||||
fields_str = ", ".join(fields)
|
# Peewee 默认使用 'id' 作为主键字段名
|
||||||
|
# 尝试获取主键字段名,如果获取失败则默认使用 'id'
|
||||||
|
primary_key_name = 'id' # 默认值
|
||||||
|
try:
|
||||||
|
if hasattr(model._meta, 'primary_key') and model._meta.primary_key:
|
||||||
|
if hasattr(model._meta.primary_key, 'name'):
|
||||||
|
primary_key_name = model._meta.primary_key.name
|
||||||
|
elif isinstance(model._meta.primary_key, str):
|
||||||
|
primary_key_name = model._meta.primary_key
|
||||||
|
except Exception:
|
||||||
|
pass # 如果获取失败,使用默认值 'id'
|
||||||
|
|
||||||
# 对于需要从 NOT NULL 改为 NULL 的字段,直接复制数据
|
# 如果字段列表包含主键,则排除它
|
||||||
# 对于需要从 NULL 改为 NOT NULL 的字段,需要处理 NULL 值
|
if primary_key_name in fields:
|
||||||
insert_sql = f"INSERT INTO {table_name} ({fields_str}) SELECT {fields_str} FROM {backup_table}"
|
fields_without_pk = [f for f in fields if f != primary_key_name]
|
||||||
|
logger.info(f"排除主键字段 '{primary_key_name}',让数据库自动生成新的主键")
|
||||||
|
else:
|
||||||
|
fields_without_pk = fields
|
||||||
|
|
||||||
|
fields_str = ", ".join(fields_without_pk)
|
||||||
|
|
||||||
# 检查是否有字段需要从 NULL 改为 NOT NULL
|
# 检查是否有字段需要从 NULL 改为 NOT NULL
|
||||||
null_to_notnull_fields = [
|
null_to_notnull_fields = [
|
||||||
|
|
@ -620,7 +639,7 @@ def _fix_table_constraints(table_name, model, constraints_to_fix):
|
||||||
|
|
||||||
# 构建更复杂的 SELECT 语句来处理 NULL 值
|
# 构建更复杂的 SELECT 语句来处理 NULL 值
|
||||||
select_fields = []
|
select_fields = []
|
||||||
for field_name in fields:
|
for field_name in fields_without_pk:
|
||||||
if field_name in null_to_notnull_fields:
|
if field_name in null_to_notnull_fields:
|
||||||
field_obj = model._meta.fields[field_name]
|
field_obj = model._meta.fields[field_name]
|
||||||
# 根据字段类型设置默认值
|
# 根据字段类型设置默认值
|
||||||
|
|
@ -641,12 +660,13 @@ def _fix_table_constraints(table_name, model, constraints_to_fix):
|
||||||
|
|
||||||
select_str = ", ".join(select_fields)
|
select_str = ", ".join(select_fields)
|
||||||
insert_sql = f"INSERT INTO {table_name} ({fields_str}) SELECT {select_str} FROM {backup_table}"
|
insert_sql = f"INSERT INTO {table_name} ({fields_str}) SELECT {select_str} FROM {backup_table}"
|
||||||
|
else:
|
||||||
|
# 没有需要处理 NULL 的字段,直接复制数据(排除主键)
|
||||||
|
insert_sql = f"INSERT INTO {table_name} ({fields_str}) SELECT {fields_str} FROM {backup_table}"
|
||||||
|
|
||||||
db.execute_sql(insert_sql)
|
db.execute_sql(insert_sql)
|
||||||
logger.info(f"已从备份表恢复数据到 '{table_name}'")
|
logger.info(f"已从备份表恢复数据到 '{table_name}'")
|
||||||
|
|
||||||
# 5. 验证数据完整性
|
|
||||||
original_count = db.execute_sql(f"SELECT COUNT(*) FROM {backup_table}").fetchone()[0]
|
|
||||||
new_count = db.execute_sql(f"SELECT COUNT(*) FROM {table_name}").fetchone()[0]
|
new_count = db.execute_sql(f"SELECT COUNT(*) FROM {table_name}").fetchone()[0]
|
||||||
|
|
||||||
if original_count == new_count:
|
if original_count == new_count:
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,6 @@ from src.config.official_configs import (
|
||||||
RelationshipConfig,
|
RelationshipConfig,
|
||||||
ToolConfig,
|
ToolConfig,
|
||||||
VoiceConfig,
|
VoiceConfig,
|
||||||
MoodConfig,
|
|
||||||
MemoryConfig,
|
MemoryConfig,
|
||||||
DebugConfig,
|
DebugConfig,
|
||||||
JargonConfig,
|
JargonConfig,
|
||||||
|
|
@ -58,7 +57,7 @@ TEMPLATE_DIR = os.path.join(PROJECT_ROOT, "template")
|
||||||
|
|
||||||
# 考虑到,实际上配置文件中的mai_version是不会自动更新的,所以采用硬编码
|
# 考虑到,实际上配置文件中的mai_version是不会自动更新的,所以采用硬编码
|
||||||
# 对该字段的更新,请严格参照语义化版本规范:https://semver.org/lang/zh-CN/
|
# 对该字段的更新,请严格参照语义化版本规范:https://semver.org/lang/zh-CN/
|
||||||
MMC_VERSION = "0.11.7-snapshot.1"
|
MMC_VERSION = "0.12.0-snapshot.1"
|
||||||
|
|
||||||
|
|
||||||
def get_key_comment(toml_table, key):
|
def get_key_comment(toml_table, key):
|
||||||
|
|
@ -355,7 +354,6 @@ class Config(ConfigBase):
|
||||||
tool: ToolConfig
|
tool: ToolConfig
|
||||||
memory: MemoryConfig
|
memory: MemoryConfig
|
||||||
debug: DebugConfig
|
debug: DebugConfig
|
||||||
mood: MoodConfig
|
|
||||||
voice: VoiceConfig
|
voice: VoiceConfig
|
||||||
jargon: JargonConfig
|
jargon: JargonConfig
|
||||||
dream: DreamConfig
|
dream: DreamConfig
|
||||||
|
|
|
||||||
|
|
@ -469,20 +469,6 @@ class ToolConfig(ConfigBase):
|
||||||
"""是否在聊天中启用工具"""
|
"""是否在聊天中启用工具"""
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class MoodConfig(ConfigBase):
|
|
||||||
"""情绪配置类"""
|
|
||||||
|
|
||||||
enable_mood: bool = True
|
|
||||||
"""是否启用情绪系统"""
|
|
||||||
|
|
||||||
mood_update_threshold: float = 1
|
|
||||||
"""情绪更新阈值,越高,更新越慢"""
|
|
||||||
|
|
||||||
emotion_style: str = "情绪较为稳定,但遭遇特定事件的时候起伏较大"
|
|
||||||
"""情感特征,影响情绪的变化情况"""
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class VoiceConfig(ConfigBase):
|
class VoiceConfig(ConfigBase):
|
||||||
"""语音识别配置类"""
|
"""语音识别配置类"""
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,6 @@ from src.config.config import global_config
|
||||||
from src.chat.message_receive.bot import chat_bot
|
from src.chat.message_receive.bot import chat_bot
|
||||||
from src.common.logger import get_logger
|
from src.common.logger import get_logger
|
||||||
from src.common.server import get_global_server, Server
|
from src.common.server import get_global_server, Server
|
||||||
from src.mood.mood_manager import mood_manager
|
|
||||||
from src.chat.knowledge import lpmm_start_up
|
from src.chat.knowledge import lpmm_start_up
|
||||||
from rich.traceback import install
|
from rich.traceback import install
|
||||||
|
|
||||||
|
|
@ -126,10 +125,6 @@ class MainSystem:
|
||||||
get_emoji_manager().initialize()
|
get_emoji_manager().initialize()
|
||||||
logger.info("表情包管理器初始化成功")
|
logger.info("表情包管理器初始化成功")
|
||||||
|
|
||||||
# 启动情绪管理器
|
|
||||||
if global_config.mood.enable_mood:
|
|
||||||
await mood_manager.start()
|
|
||||||
logger.info("情绪管理器初始化成功")
|
|
||||||
|
|
||||||
# 初始化聊天管理器
|
# 初始化聊天管理器
|
||||||
await get_chat_manager()._initialize()
|
await get_chat_manager()._initialize()
|
||||||
|
|
|
||||||
|
|
@ -1,230 +0,0 @@
|
||||||
import time
|
|
||||||
|
|
||||||
from src.common.logger import get_logger
|
|
||||||
from src.config.config import global_config, model_config
|
|
||||||
from src.chat.message_receive.chat_stream import get_chat_manager
|
|
||||||
from src.chat.utils.prompt_builder import Prompt, global_prompt_manager
|
|
||||||
from src.chat.utils.chat_message_builder import build_readable_messages, get_raw_msg_by_timestamp_with_chat_inclusive
|
|
||||||
from src.llm_models.utils_model import LLMRequest
|
|
||||||
from src.manager.async_task_manager import AsyncTask, async_task_manager
|
|
||||||
|
|
||||||
|
|
||||||
logger = get_logger("mood")
|
|
||||||
|
|
||||||
|
|
||||||
def init_prompt():
|
|
||||||
Prompt(
|
|
||||||
"""
|
|
||||||
{chat_talking_prompt}
|
|
||||||
以上是群里正在进行的聊天记录
|
|
||||||
|
|
||||||
{identity_block}
|
|
||||||
你先前的情绪状态是:{mood_state}
|
|
||||||
你的情绪特点是:{emotion_style}
|
|
||||||
|
|
||||||
现在,请你根据先前的情绪状态和现在的聊天内容,总结推断你现在的情绪状态,用简短的词句来描述情绪状态
|
|
||||||
请只输出新的情绪状态,不要输出其他内容:
|
|
||||||
""",
|
|
||||||
"get_mood_prompt",
|
|
||||||
)
|
|
||||||
|
|
||||||
Prompt(
|
|
||||||
"""
|
|
||||||
{chat_talking_prompt}
|
|
||||||
以上是群里最近的聊天记录
|
|
||||||
|
|
||||||
{identity_block}
|
|
||||||
你之前的情绪状态是:{mood_state}
|
|
||||||
|
|
||||||
距离你上次关注群里消息已经过去了一段时间,你冷静了下来,请你输出一句话或几个词来描述你现在的情绪状态
|
|
||||||
你的情绪特点是:{emotion_style}
|
|
||||||
请只输出新的情绪状态,不要输出其他内容:
|
|
||||||
""",
|
|
||||||
"regress_mood_prompt",
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class ChatMood:
|
|
||||||
def __init__(self, chat_id: str):
|
|
||||||
self.chat_id: str = chat_id
|
|
||||||
|
|
||||||
chat_manager = get_chat_manager()
|
|
||||||
self.chat_stream = chat_manager.get_stream(self.chat_id)
|
|
||||||
|
|
||||||
if not self.chat_stream:
|
|
||||||
raise ValueError(f"Chat stream for chat_id {chat_id} not found")
|
|
||||||
|
|
||||||
self.log_prefix = f"[{self.chat_stream.group_info.group_name if self.chat_stream.group_info else self.chat_stream.user_info.user_nickname}]"
|
|
||||||
|
|
||||||
self.mood_state: str = "感觉很平静"
|
|
||||||
|
|
||||||
self.regression_count: int = 0
|
|
||||||
|
|
||||||
self.mood_model = LLMRequest(model_set=model_config.model_task_config.utils, request_type="mood")
|
|
||||||
|
|
||||||
self.last_change_time: float = 0
|
|
||||||
|
|
||||||
async def get_mood(self) -> str:
|
|
||||||
self.regression_count = 0
|
|
||||||
|
|
||||||
current_time = time.time()
|
|
||||||
|
|
||||||
logger.info(f"{self.log_prefix} 获取情绪状态")
|
|
||||||
message_list_before_now = get_raw_msg_by_timestamp_with_chat_inclusive(
|
|
||||||
chat_id=self.chat_id,
|
|
||||||
timestamp_start=self.last_change_time,
|
|
||||||
timestamp_end=current_time,
|
|
||||||
limit=int(global_config.chat.max_context_size / 3),
|
|
||||||
limit_mode="last",
|
|
||||||
)
|
|
||||||
|
|
||||||
chat_talking_prompt = build_readable_messages(
|
|
||||||
message_list_before_now,
|
|
||||||
replace_bot_name=True,
|
|
||||||
timestamp_mode="normal_no_YMD",
|
|
||||||
read_mark=0.0,
|
|
||||||
truncate=True,
|
|
||||||
show_actions=True,
|
|
||||||
)
|
|
||||||
|
|
||||||
bot_name = global_config.bot.nickname
|
|
||||||
if global_config.bot.alias_names:
|
|
||||||
bot_nickname = f",也有人叫你{','.join(global_config.bot.alias_names)}"
|
|
||||||
else:
|
|
||||||
bot_nickname = ""
|
|
||||||
|
|
||||||
identity_block = f"你的名字是{bot_name}{bot_nickname}"
|
|
||||||
|
|
||||||
prompt = await global_prompt_manager.format_prompt(
|
|
||||||
"get_mood_prompt",
|
|
||||||
chat_talking_prompt=chat_talking_prompt,
|
|
||||||
identity_block=identity_block,
|
|
||||||
mood_state=self.mood_state,
|
|
||||||
emotion_style=global_config.mood.emotion_style,
|
|
||||||
)
|
|
||||||
|
|
||||||
response, (reasoning_content, _, _) = await self.mood_model.generate_response_async(
|
|
||||||
prompt=prompt, temperature=0.7
|
|
||||||
)
|
|
||||||
if global_config.debug.show_prompt:
|
|
||||||
logger.info(f"{self.log_prefix} prompt: {prompt}")
|
|
||||||
logger.info(f"{self.log_prefix} response: {response}")
|
|
||||||
logger.info(f"{self.log_prefix} reasoning_content: {reasoning_content}")
|
|
||||||
|
|
||||||
logger.info(f"{self.log_prefix} 情绪状态更新为: {response}")
|
|
||||||
|
|
||||||
self.mood_state = response
|
|
||||||
|
|
||||||
self.last_change_time = current_time
|
|
||||||
|
|
||||||
return response
|
|
||||||
|
|
||||||
async def regress_mood(self):
|
|
||||||
message_time = time.time()
|
|
||||||
message_list_before_now = get_raw_msg_by_timestamp_with_chat_inclusive(
|
|
||||||
chat_id=self.chat_id,
|
|
||||||
timestamp_start=self.last_change_time,
|
|
||||||
timestamp_end=message_time,
|
|
||||||
limit=15,
|
|
||||||
limit_mode="last",
|
|
||||||
)
|
|
||||||
|
|
||||||
chat_talking_prompt = build_readable_messages(
|
|
||||||
message_list_before_now,
|
|
||||||
replace_bot_name=True,
|
|
||||||
timestamp_mode="normal_no_YMD",
|
|
||||||
read_mark=0.0,
|
|
||||||
truncate=True,
|
|
||||||
show_actions=True,
|
|
||||||
)
|
|
||||||
|
|
||||||
bot_name = global_config.bot.nickname
|
|
||||||
if global_config.bot.alias_names:
|
|
||||||
bot_nickname = f",也有人叫你{','.join(global_config.bot.alias_names)}"
|
|
||||||
else:
|
|
||||||
bot_nickname = ""
|
|
||||||
|
|
||||||
identity_block = f"你的名字是{bot_name}{bot_nickname}"
|
|
||||||
|
|
||||||
prompt = await global_prompt_manager.format_prompt(
|
|
||||||
"regress_mood_prompt",
|
|
||||||
chat_talking_prompt=chat_talking_prompt,
|
|
||||||
identity_block=identity_block,
|
|
||||||
mood_state=self.mood_state,
|
|
||||||
emotion_style=global_config.mood.emotion_style,
|
|
||||||
)
|
|
||||||
|
|
||||||
response, (reasoning_content, _, _) = await self.mood_model.generate_response_async(
|
|
||||||
prompt=prompt, temperature=0.7
|
|
||||||
)
|
|
||||||
|
|
||||||
if global_config.debug.show_prompt:
|
|
||||||
logger.info(f"{self.log_prefix} prompt: {prompt}")
|
|
||||||
logger.info(f"{self.log_prefix} response: {response}")
|
|
||||||
logger.info(f"{self.log_prefix} reasoning_content: {reasoning_content}")
|
|
||||||
|
|
||||||
logger.info(f"{self.log_prefix} 情绪状态转变为: {response}")
|
|
||||||
|
|
||||||
self.mood_state = response
|
|
||||||
|
|
||||||
self.regression_count += 1
|
|
||||||
|
|
||||||
|
|
||||||
class MoodRegressionTask(AsyncTask):
|
|
||||||
def __init__(self, mood_manager: "MoodManager"):
|
|
||||||
super().__init__(task_name="MoodRegressionTask", run_interval=45)
|
|
||||||
self.mood_manager = mood_manager
|
|
||||||
|
|
||||||
async def run(self):
|
|
||||||
logger.debug("开始情绪回归任务...")
|
|
||||||
now = time.time()
|
|
||||||
for mood in self.mood_manager.mood_list:
|
|
||||||
if mood.last_change_time == 0:
|
|
||||||
continue
|
|
||||||
|
|
||||||
if now - mood.last_change_time > 200:
|
|
||||||
if mood.regression_count >= 2:
|
|
||||||
continue
|
|
||||||
|
|
||||||
logger.debug(f"{mood.log_prefix} 开始情绪回归, 第 {mood.regression_count + 1} 次")
|
|
||||||
await mood.regress_mood()
|
|
||||||
|
|
||||||
|
|
||||||
class MoodManager:
|
|
||||||
def __init__(self):
|
|
||||||
self.mood_list: list[ChatMood] = []
|
|
||||||
"""当前情绪状态"""
|
|
||||||
self.task_started: bool = False
|
|
||||||
|
|
||||||
async def start(self):
|
|
||||||
"""启动情绪回归后台任务"""
|
|
||||||
if self.task_started:
|
|
||||||
return
|
|
||||||
|
|
||||||
task = MoodRegressionTask(self)
|
|
||||||
await async_task_manager.add_task(task)
|
|
||||||
self.task_started = True
|
|
||||||
logger.info("情绪回归任务已启动")
|
|
||||||
|
|
||||||
def get_mood_by_chat_id(self, chat_id: str) -> ChatMood:
|
|
||||||
for mood in self.mood_list:
|
|
||||||
if mood.chat_id == chat_id:
|
|
||||||
return mood
|
|
||||||
|
|
||||||
new_mood = ChatMood(chat_id)
|
|
||||||
self.mood_list.append(new_mood)
|
|
||||||
return new_mood
|
|
||||||
|
|
||||||
def reset_mood_by_chat_id(self, chat_id: str):
|
|
||||||
for mood in self.mood_list:
|
|
||||||
if mood.chat_id == chat_id:
|
|
||||||
mood.mood_state = "感觉很平静"
|
|
||||||
mood.regression_count = 0
|
|
||||||
return
|
|
||||||
self.mood_list.append(ChatMood(chat_id))
|
|
||||||
|
|
||||||
|
|
||||||
init_prompt()
|
|
||||||
|
|
||||||
mood_manager = MoodManager()
|
|
||||||
"""全局情绪管理器"""
|
|
||||||
|
|
@ -19,7 +19,6 @@ from src.plugin_system.apis import (
|
||||||
send_api,
|
send_api,
|
||||||
tool_api,
|
tool_api,
|
||||||
frequency_api,
|
frequency_api,
|
||||||
mood_api,
|
|
||||||
auto_talk_api,
|
auto_talk_api,
|
||||||
)
|
)
|
||||||
from .logging_api import get_logger
|
from .logging_api import get_logger
|
||||||
|
|
@ -42,6 +41,5 @@ __all__ = [
|
||||||
"register_plugin",
|
"register_plugin",
|
||||||
"tool_api",
|
"tool_api",
|
||||||
"frequency_api",
|
"frequency_api",
|
||||||
"mood_api",
|
|
||||||
"auto_talk_api",
|
"auto_talk_api",
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
import asyncio
|
|
||||||
from typing import Optional
|
|
||||||
|
|
||||||
from src.common.logger import get_logger
|
|
||||||
from src.mood.mood_manager import mood_manager
|
|
||||||
|
|
||||||
logger = get_logger("mood_api")
|
|
||||||
|
|
||||||
|
|
||||||
async def get_mood_by_chat_id(chat_id: str) -> Optional[float]:
|
|
||||||
chat_mood = mood_manager.get_mood_by_chat_id(chat_id)
|
|
||||||
mood = asyncio.create_task(chat_mood.get_mood())
|
|
||||||
return mood
|
|
||||||
|
|
@ -29,7 +29,6 @@ from src.config.official_configs import (
|
||||||
ToolConfig,
|
ToolConfig,
|
||||||
MemoryConfig,
|
MemoryConfig,
|
||||||
DebugConfig,
|
DebugConfig,
|
||||||
MoodConfig,
|
|
||||||
VoiceConfig,
|
VoiceConfig,
|
||||||
JargonConfig,
|
JargonConfig,
|
||||||
)
|
)
|
||||||
|
|
@ -104,7 +103,6 @@ async def get_config_section_schema(section_name: str):
|
||||||
- tool: ToolConfig
|
- tool: ToolConfig
|
||||||
- memory: MemoryConfig
|
- memory: MemoryConfig
|
||||||
- debug: DebugConfig
|
- debug: DebugConfig
|
||||||
- mood: MoodConfig
|
|
||||||
- voice: VoiceConfig
|
- voice: VoiceConfig
|
||||||
- jargon: JargonConfig
|
- jargon: JargonConfig
|
||||||
- model_task_config: ModelTaskConfig
|
- model_task_config: ModelTaskConfig
|
||||||
|
|
@ -130,7 +128,6 @@ async def get_config_section_schema(section_name: str):
|
||||||
"tool": ToolConfig,
|
"tool": ToolConfig,
|
||||||
"memory": MemoryConfig,
|
"memory": MemoryConfig,
|
||||||
"debug": DebugConfig,
|
"debug": DebugConfig,
|
||||||
"mood": MoodConfig,
|
|
||||||
"voice": VoiceConfig,
|
"voice": VoiceConfig,
|
||||||
"jargon": JargonConfig,
|
"jargon": JargonConfig,
|
||||||
"model_task_config": ModelTaskConfig,
|
"model_task_config": ModelTaskConfig,
|
||||||
|
|
|
||||||
|
|
@ -296,7 +296,6 @@ class ConfigSchemaGenerator:
|
||||||
"plan_style",
|
"plan_style",
|
||||||
"visual_style",
|
"visual_style",
|
||||||
"private_plan_style",
|
"private_plan_style",
|
||||||
"emotion_style",
|
|
||||||
"reaction",
|
"reaction",
|
||||||
"filtration_prompt",
|
"filtration_prompt",
|
||||||
]:
|
]:
|
||||||
|
|
|
||||||
|
|
@ -137,11 +137,6 @@ all_global = true # 是否开启全局黑话模式,注意,此功能关闭后
|
||||||
[tool]
|
[tool]
|
||||||
enable_tool = true # 是否启用工具
|
enable_tool = true # 是否启用工具
|
||||||
|
|
||||||
[mood]
|
|
||||||
enable_mood = false # 是否启用情绪系统
|
|
||||||
mood_update_threshold = 1 # 情绪更新阈值,越高,更新越慢
|
|
||||||
# 情感特征,影响情绪的变化情况
|
|
||||||
emotion_style = "情绪较为稳定,但遭遇特定事件的时候起伏较大"
|
|
||||||
|
|
||||||
[emoji]
|
[emoji]
|
||||||
emoji_chance = 0.4 # 麦麦激活表情包动作的概率
|
emoji_chance = 0.4 # 麦麦激活表情包动作的概率
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue