fix:优化离开focus模式的机制,完全移除Interest机制,
This commit is contained in:
@@ -33,11 +33,11 @@ async def get_subheartflow_cycle_info(subheartflow_id: str, history_len: int) ->
|
|||||||
|
|
||||||
async def get_normal_chat_replies(subheartflow_id: str, limit: int = 10) -> list:
|
async def get_normal_chat_replies(subheartflow_id: str, limit: int = 10) -> list:
|
||||||
"""获取子心流的NormalChat回复记录
|
"""获取子心流的NormalChat回复记录
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
subheartflow_id: 子心流ID
|
subheartflow_id: 子心流ID
|
||||||
limit: 最大返回数量,默认10条
|
limit: 最大返回数量,默认10条
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
list: 回复记录列表,如果未找到则返回空列表
|
list: 回复记录列表,如果未找到则返回空列表
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ from src.chat.emoji_system.emoji_manager import emoji_manager
|
|||||||
from src.chat.focus_chat.heartFC_sender import HeartFCSender
|
from src.chat.focus_chat.heartFC_sender import HeartFCSender
|
||||||
from src.chat.utils.utils import process_llm_response
|
from src.chat.utils.utils import process_llm_response
|
||||||
from src.chat.utils.info_catcher import info_catcher_manager
|
from src.chat.utils.info_catcher import info_catcher_manager
|
||||||
from src.manager.mood_manager import mood_manager
|
|
||||||
from src.chat.heart_flow.utils_chat import get_chat_type_and_target_info
|
from src.chat.heart_flow.utils_chat import get_chat_type_and_target_info
|
||||||
from src.chat.message_receive.chat_stream import ChatStream
|
from src.chat.message_receive.chat_stream import ChatStream
|
||||||
from src.chat.focus_chat.hfc_utils import parse_thinking_id_to_timestamp
|
from src.chat.focus_chat.hfc_utils import parse_thinking_id_to_timestamp
|
||||||
@@ -150,22 +149,22 @@ class DefaultExpressor:
|
|||||||
action_data=action_data,
|
action_data=action_data,
|
||||||
)
|
)
|
||||||
|
|
||||||
with Timer("选择表情", cycle_timers):
|
with Timer("选择表情", cycle_timers):
|
||||||
emoji_keyword = action_data.get("emojis", [])
|
emoji_keyword = action_data.get("emojis", [])
|
||||||
emoji_base64 = await self._choose_emoji(emoji_keyword)
|
emoji_base64 = await self._choose_emoji(emoji_keyword)
|
||||||
if emoji_base64:
|
if emoji_base64:
|
||||||
reply.append(("emoji", emoji_base64))
|
reply.append(("emoji", emoji_base64))
|
||||||
|
|
||||||
if reply:
|
if reply:
|
||||||
with Timer("发送消息", cycle_timers):
|
with Timer("发送消息", cycle_timers):
|
||||||
sent_msg_list = await self.send_response_messages(
|
sent_msg_list = await self.send_response_messages(
|
||||||
anchor_message=anchor_message,
|
anchor_message=anchor_message,
|
||||||
thinking_id=thinking_id,
|
thinking_id=thinking_id,
|
||||||
response_set=reply,
|
response_set=reply,
|
||||||
)
|
)
|
||||||
has_sent_something = True
|
has_sent_something = True
|
||||||
else:
|
else:
|
||||||
logger.warning(f"{self.log_prefix} 文本回复生成失败")
|
logger.warning(f"{self.log_prefix} 文本回复生成失败")
|
||||||
|
|
||||||
if not has_sent_something:
|
if not has_sent_something:
|
||||||
logger.warning(f"{self.log_prefix} 回复动作未包含任何有效内容")
|
logger.warning(f"{self.log_prefix} 回复动作未包含任何有效内容")
|
||||||
@@ -174,6 +173,7 @@ class DefaultExpressor:
|
|||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"回复失败: {e}")
|
logger.error(f"回复失败: {e}")
|
||||||
|
traceback.print_exc()
|
||||||
return False, None
|
return False, None
|
||||||
|
|
||||||
# --- 回复器 (Replier) 的定义 --- #
|
# --- 回复器 (Replier) 的定义 --- #
|
||||||
@@ -443,7 +443,9 @@ class DefaultExpressor:
|
|||||||
set_reply = True
|
set_reply = True
|
||||||
else:
|
else:
|
||||||
set_reply = False
|
set_reply = False
|
||||||
sent_msg = await self.heart_fc_sender.send_message(bot_message, has_thinking=True, typing=typing, set_reply=set_reply)
|
sent_msg = await self.heart_fc_sender.send_message(
|
||||||
|
bot_message, has_thinking=True, typing=typing, set_reply=set_reply
|
||||||
|
)
|
||||||
|
|
||||||
reply_message_ids.append(part_message_id) # 记录我们生成的ID
|
reply_message_ids.append(part_message_id) # 记录我们生成的ID
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import contextlib
|
|||||||
import time
|
import time
|
||||||
import traceback
|
import traceback
|
||||||
from collections import deque
|
from collections import deque
|
||||||
from typing import List, Optional, Dict, Any, Deque
|
from typing import List, Optional, Dict, Any, Deque, Callable, Awaitable
|
||||||
from src.chat.message_receive.chat_stream import ChatStream
|
from src.chat.message_receive.chat_stream import ChatStream
|
||||||
from src.chat.message_receive.chat_stream import chat_manager
|
from src.chat.message_receive.chat_stream import chat_manager
|
||||||
from rich.traceback import install
|
from rich.traceback import install
|
||||||
@@ -84,6 +84,7 @@ class HeartFChatting:
|
|||||||
self,
|
self,
|
||||||
chat_id: str,
|
chat_id: str,
|
||||||
observations: list[Observation],
|
observations: list[Observation],
|
||||||
|
on_stop_focus_chat: Optional[Callable[[], Awaitable[None]]] = None,
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
HeartFChatting 初始化函数
|
HeartFChatting 初始化函数
|
||||||
@@ -91,6 +92,7 @@ class HeartFChatting:
|
|||||||
参数:
|
参数:
|
||||||
chat_id: 聊天流唯一标识符(如stream_id)
|
chat_id: 聊天流唯一标识符(如stream_id)
|
||||||
observations: 关联的观察列表
|
observations: 关联的观察列表
|
||||||
|
on_stop_focus_chat: 当收到stop_focus_chat命令时调用的回调函数
|
||||||
"""
|
"""
|
||||||
# 基础属性
|
# 基础属性
|
||||||
self.stream_id: str = chat_id # 聊天流ID
|
self.stream_id: str = chat_id # 聊天流ID
|
||||||
@@ -143,6 +145,9 @@ class HeartFChatting:
|
|||||||
self._current_cycle: Optional[CycleDetail] = None
|
self._current_cycle: Optional[CycleDetail] = None
|
||||||
self._shutting_down: bool = False # 关闭标志位
|
self._shutting_down: bool = False # 关闭标志位
|
||||||
|
|
||||||
|
# 存储回调函数
|
||||||
|
self.on_stop_focus_chat = on_stop_focus_chat
|
||||||
|
|
||||||
async def _initialize(self) -> bool:
|
async def _initialize(self) -> bool:
|
||||||
"""
|
"""
|
||||||
执行懒初始化操作
|
执行懒初始化操作
|
||||||
@@ -287,6 +292,19 @@ class HeartFChatting:
|
|||||||
async with global_prompt_manager.async_message_scope(self.chat_stream.context.get_template_name()):
|
async with global_prompt_manager.async_message_scope(self.chat_stream.context.get_template_name()):
|
||||||
logger.debug(f"模板 {self.chat_stream.context.get_template_name()}")
|
logger.debug(f"模板 {self.chat_stream.context.get_template_name()}")
|
||||||
loop_info = await self._observe_process_plan_action_loop(cycle_timers, thinking_id)
|
loop_info = await self._observe_process_plan_action_loop(cycle_timers, thinking_id)
|
||||||
|
|
||||||
|
print(loop_info["loop_action_info"]["command"])
|
||||||
|
if loop_info["loop_action_info"]["command"] == "stop_focus_chat":
|
||||||
|
logger.info(f"{self.log_prefix} 麦麦决定停止专注聊天")
|
||||||
|
# 如果设置了回调函数,则调用它
|
||||||
|
if self.on_stop_focus_chat:
|
||||||
|
try:
|
||||||
|
await self.on_stop_focus_chat()
|
||||||
|
logger.info(f"{self.log_prefix} 成功调用回调函数处理停止专注聊天")
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"{self.log_prefix} 调用停止专注聊天回调函数时出错: {e}")
|
||||||
|
logger.error(traceback.format_exc())
|
||||||
|
break
|
||||||
|
|
||||||
self._current_cycle.set_loop_info(loop_info)
|
self._current_cycle.set_loop_info(loop_info)
|
||||||
|
|
||||||
@@ -410,7 +428,7 @@ class HeartFChatting:
|
|||||||
|
|
||||||
return all_plan_info
|
return all_plan_info
|
||||||
|
|
||||||
async def _observe_process_plan_action_loop(self, cycle_timers: dict, thinking_id: str) -> tuple[bool, str]:
|
async def _observe_process_plan_action_loop(self, cycle_timers: dict, thinking_id: str) -> dict:
|
||||||
try:
|
try:
|
||||||
with Timer("观察", cycle_timers):
|
with Timer("观察", cycle_timers):
|
||||||
# await self.observations[0].observe()
|
# await self.observations[0].observe()
|
||||||
@@ -466,13 +484,14 @@ class HeartFChatting:
|
|||||||
|
|
||||||
logger.info(f"{self.log_prefix} 麦麦决定'{action_str}', 原因'{reasoning}'")
|
logger.info(f"{self.log_prefix} 麦麦决定'{action_str}', 原因'{reasoning}'")
|
||||||
|
|
||||||
success, reply_text = await self._handle_action(
|
success, reply_text, command = await self._handle_action(
|
||||||
action_type, reasoning, action_data, cycle_timers, thinking_id
|
action_type, reasoning, action_data, cycle_timers, thinking_id
|
||||||
)
|
)
|
||||||
|
|
||||||
loop_action_info = {
|
loop_action_info = {
|
||||||
"action_taken": success,
|
"action_taken": success,
|
||||||
"reply_text": reply_text,
|
"reply_text": reply_text,
|
||||||
|
"command": command,
|
||||||
}
|
}
|
||||||
|
|
||||||
loop_info = {
|
loop_info = {
|
||||||
@@ -487,7 +506,12 @@ class HeartFChatting:
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"{self.log_prefix} FOCUS聊天处理失败: {e}")
|
logger.error(f"{self.log_prefix} FOCUS聊天处理失败: {e}")
|
||||||
logger.error(traceback.format_exc())
|
logger.error(traceback.format_exc())
|
||||||
return {}
|
return {
|
||||||
|
"loop_observation_info": {},
|
||||||
|
"loop_processor_info": {},
|
||||||
|
"loop_plan_info": {},
|
||||||
|
"loop_action_info": {"action_taken": False, "reply_text": "", "command": ""},
|
||||||
|
}
|
||||||
|
|
||||||
async def _handle_action(
|
async def _handle_action(
|
||||||
self,
|
self,
|
||||||
@@ -496,7 +520,7 @@ class HeartFChatting:
|
|||||||
action_data: dict,
|
action_data: dict,
|
||||||
cycle_timers: dict,
|
cycle_timers: dict,
|
||||||
thinking_id: str,
|
thinking_id: str,
|
||||||
) -> tuple[bool, str]:
|
) -> tuple[bool, str, str]:
|
||||||
"""
|
"""
|
||||||
处理规划动作,使用动作工厂创建相应的动作处理器
|
处理规划动作,使用动作工厂创建相应的动作处理器
|
||||||
|
|
||||||
@@ -508,36 +532,46 @@ class HeartFChatting:
|
|||||||
thinking_id: 思考ID
|
thinking_id: 思考ID
|
||||||
|
|
||||||
返回:
|
返回:
|
||||||
tuple[bool, str]: (是否执行了动作, 思考消息ID)
|
tuple[bool, str, str]: (是否执行了动作, 思考消息ID, 命令)
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
# 使用工厂创建动作处理器实例
|
# 使用工厂创建动作处理器实例
|
||||||
action_handler = self.action_manager.create_action(
|
try:
|
||||||
action_name=action,
|
action_handler = self.action_manager.create_action(
|
||||||
action_data=action_data,
|
action_name=action,
|
||||||
reasoning=reasoning,
|
action_data=action_data,
|
||||||
cycle_timers=cycle_timers,
|
reasoning=reasoning,
|
||||||
thinking_id=thinking_id,
|
cycle_timers=cycle_timers,
|
||||||
observations=self.all_observations,
|
thinking_id=thinking_id,
|
||||||
expressor=self.expressor,
|
observations=self.all_observations,
|
||||||
chat_stream=self.chat_stream,
|
expressor=self.expressor,
|
||||||
log_prefix=self.log_prefix,
|
chat_stream=self.chat_stream,
|
||||||
shutting_down=self._shutting_down,
|
log_prefix=self.log_prefix,
|
||||||
)
|
shutting_down=self._shutting_down,
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"{self.log_prefix} 创建动作处理器时出错: {e}")
|
||||||
|
traceback.print_exc()
|
||||||
|
return False, "", ""
|
||||||
|
|
||||||
if not action_handler:
|
if not action_handler:
|
||||||
logger.warning(f"{self.log_prefix} 未能创建动作处理器: {action}, 原因: {reasoning}")
|
logger.warning(f"{self.log_prefix} 未能创建动作处理器: {action}, 原因: {reasoning}")
|
||||||
return False, ""
|
return False, "", ""
|
||||||
|
|
||||||
# 处理动作并获取结果
|
# 处理动作并获取结果
|
||||||
success, reply_text = await action_handler.handle_action()
|
result = await action_handler.handle_action()
|
||||||
|
if len(result) == 3:
|
||||||
return success, reply_text
|
success, reply_text, command = result
|
||||||
|
else:
|
||||||
|
success, reply_text = result
|
||||||
|
command = ""
|
||||||
|
logger.info(f"{self.log_prefix} 麦麦决定'{action}', 原因'{reasoning}',返回结果'{success}', '{reply_text}', '{command}'")
|
||||||
|
return success, reply_text, command
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"{self.log_prefix} 处理{action}时出错: {e}")
|
logger.error(f"{self.log_prefix} 处理{action}时出错: {e}")
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
return False, ""
|
return False, "", ""
|
||||||
|
|
||||||
async def shutdown(self):
|
async def shutdown(self):
|
||||||
"""优雅关闭HeartFChatting实例,取消活动循环任务"""
|
"""优雅关闭HeartFChatting实例,取消活动循环任务"""
|
||||||
|
|||||||
@@ -205,8 +205,8 @@ class HeartFCMessageReceiver:
|
|||||||
|
|
||||||
# 6. 兴趣度计算与更新
|
# 6. 兴趣度计算与更新
|
||||||
interested_rate, is_mentioned = await _calculate_interest(message)
|
interested_rate, is_mentioned = await _calculate_interest(message)
|
||||||
await subheartflow.interest_chatting.increase_interest(value=interested_rate)
|
# await subheartflow.interest_chatting.increase_interest(value=interested_rate)
|
||||||
subheartflow.interest_chatting.add_interest_dict(message, interested_rate, is_mentioned)
|
subheartflow.add_interest_message(message, interested_rate, is_mentioned)
|
||||||
|
|
||||||
# 7. 日志记录
|
# 7. 日志记录
|
||||||
mes_name = chat.group_info.group_name if chat.group_info else "私聊"
|
mes_name = chat.group_info.group_name if chat.group_info else "私聊"
|
||||||
|
|||||||
@@ -77,9 +77,8 @@ class StructuredInfo:
|
|||||||
|
|
||||||
info_str = ""
|
info_str = ""
|
||||||
# print(f"self.data: {self.data}")
|
# print(f"self.data: {self.data}")
|
||||||
|
|
||||||
for key, value in self.data.items():
|
for key, value in self.data.items():
|
||||||
|
|
||||||
# print(f"key: {key}, value: {value}")
|
# print(f"key: {key}, value: {value}")
|
||||||
info_str += f"信息类型:{key},信息内容:{value}\n"
|
info_str += f"信息类型:{key},信息内容:{value}\n"
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ from src.chat.heart_flow.observation.hfcloop_observation import HFCloopObservati
|
|||||||
from src.chat.heart_flow.observation.chatting_observation import ChattingObservation
|
from src.chat.heart_flow.observation.chatting_observation import ChattingObservation
|
||||||
from src.chat.message_receive.chat_stream import chat_manager
|
from src.chat.message_receive.chat_stream import chat_manager
|
||||||
from typing import Dict
|
from typing import Dict
|
||||||
from src.llm_models.utils_model import LLMRequest
|
|
||||||
from src.config.config import global_config
|
from src.config.config import global_config
|
||||||
import random
|
import random
|
||||||
|
|
||||||
@@ -137,9 +136,11 @@ class ActionProcessor(BaseProcessor):
|
|||||||
reply_sequence.append(action_type == "reply")
|
reply_sequence.append(action_type == "reply")
|
||||||
|
|
||||||
# 检查no_reply比例
|
# 检查no_reply比例
|
||||||
if len(recent_cycles) >= 5 and (no_reply_count / len(recent_cycles)) >= 0.8:
|
if len(recent_cycles) >= (5 * global_config.focus_chat.exit_focus_threshold) and (no_reply_count / len(recent_cycles)) >= (0.75 * global_config.focus_chat.exit_focus_threshold):
|
||||||
if global_config.chat.chat_mode == "auto":
|
if global_config.chat.chat_mode == "auto":
|
||||||
result["add"].append("exit_focus_chat")
|
result["add"].append("exit_focus_chat")
|
||||||
|
result["remove"].append("no_reply")
|
||||||
|
result["remove"].append("reply")
|
||||||
|
|
||||||
# 获取最近三次的reply状态
|
# 获取最近三次的reply状态
|
||||||
last_three = reply_sequence[-3:] if len(reply_sequence) >= 3 else reply_sequence
|
last_three = reply_sequence[-3:] if len(reply_sequence) >= 3 else reply_sequence
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ class ToolProcessor(BaseProcessor):
|
|||||||
|
|
||||||
# 更新WorkingObservation中的结构化信息
|
# 更新WorkingObservation中的结构化信息
|
||||||
logger.debug(f"工具调用结果: {result}")
|
logger.debug(f"工具调用结果: {result}")
|
||||||
|
|
||||||
for observation in observations:
|
for observation in observations:
|
||||||
if isinstance(observation, StructureObservation):
|
if isinstance(observation, StructureObservation):
|
||||||
for structured_info in result:
|
for structured_info in result:
|
||||||
@@ -92,7 +92,7 @@ class ToolProcessor(BaseProcessor):
|
|||||||
# print(f"working_info: {working_info}")
|
# print(f"working_info: {working_info}")
|
||||||
# print(f"working_info.get('type'): {working_info.get('type')}")
|
# print(f"working_info.get('type'): {working_info.get('type')}")
|
||||||
# print(f"working_info.get('content'): {working_info.get('content')}")
|
# print(f"working_info.get('content'): {working_info.get('content')}")
|
||||||
structured_info.set_info(key=working_info.get('type'), value=working_info.get('content'))
|
structured_info.set_info(key=working_info.get("type"), value=working_info.get("content"))
|
||||||
# info = structured_info.get_processed_info()
|
# info = structured_info.get_processed_info()
|
||||||
# print(f"info: {info}")
|
# print(f"info: {info}")
|
||||||
|
|
||||||
|
|||||||
@@ -19,24 +19,24 @@ logger = get_logger("memory_activator")
|
|||||||
def get_keywords_from_json(json_str):
|
def get_keywords_from_json(json_str):
|
||||||
"""
|
"""
|
||||||
从JSON字符串中提取关键词列表
|
从JSON字符串中提取关键词列表
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
json_str: JSON格式的字符串
|
json_str: JSON格式的字符串
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
List[str]: 关键词列表
|
List[str]: 关键词列表
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
# 使用repair_json修复JSON格式
|
# 使用repair_json修复JSON格式
|
||||||
fixed_json = repair_json(json_str)
|
fixed_json = repair_json(json_str)
|
||||||
|
|
||||||
# 如果repair_json返回的是字符串,需要解析为Python对象
|
# 如果repair_json返回的是字符串,需要解析为Python对象
|
||||||
if isinstance(fixed_json, str):
|
if isinstance(fixed_json, str):
|
||||||
result = json.loads(fixed_json)
|
result = json.loads(fixed_json)
|
||||||
else:
|
else:
|
||||||
# 如果repair_json直接返回了字典对象,直接使用
|
# 如果repair_json直接返回了字典对象,直接使用
|
||||||
result = fixed_json
|
result = fixed_json
|
||||||
|
|
||||||
# 提取关键词
|
# 提取关键词
|
||||||
keywords = result.get("keywords", [])
|
keywords = result.get("keywords", [])
|
||||||
return keywords
|
return keywords
|
||||||
@@ -100,7 +100,7 @@ class MemoryActivator:
|
|||||||
|
|
||||||
# 将缓存的关键词转换为字符串,用于prompt
|
# 将缓存的关键词转换为字符串,用于prompt
|
||||||
cached_keywords_str = ", ".join(self.cached_keywords) if self.cached_keywords else "暂无历史关键词"
|
cached_keywords_str = ", ".join(self.cached_keywords) if self.cached_keywords else "暂无历史关键词"
|
||||||
|
|
||||||
prompt = await global_prompt_manager.format_prompt(
|
prompt = await global_prompt_manager.format_prompt(
|
||||||
"memory_activator_prompt",
|
"memory_activator_prompt",
|
||||||
obs_info_text=obs_info_text,
|
obs_info_text=obs_info_text,
|
||||||
@@ -116,7 +116,7 @@ class MemoryActivator:
|
|||||||
# 只取response的第一个元素(字符串)
|
# 只取response的第一个元素(字符串)
|
||||||
response_str = response[0]
|
response_str = response[0]
|
||||||
keywords = list(get_keywords_from_json(response_str))
|
keywords = list(get_keywords_from_json(response_str))
|
||||||
|
|
||||||
# 更新关键词缓存
|
# 更新关键词缓存
|
||||||
if keywords:
|
if keywords:
|
||||||
# 限制缓存大小,最多保留10个关键词
|
# 限制缓存大小,最多保留10个关键词
|
||||||
@@ -124,12 +124,12 @@ class MemoryActivator:
|
|||||||
# 转换为列表,移除最早的关键词
|
# 转换为列表,移除最早的关键词
|
||||||
cached_list = list(self.cached_keywords)
|
cached_list = list(self.cached_keywords)
|
||||||
self.cached_keywords = set(cached_list[-8:])
|
self.cached_keywords = set(cached_list[-8:])
|
||||||
|
|
||||||
# 添加新的关键词到缓存
|
# 添加新的关键词到缓存
|
||||||
self.cached_keywords.update(keywords)
|
self.cached_keywords.update(keywords)
|
||||||
logger.debug(f"更新关键词缓存: {self.cached_keywords}")
|
logger.debug(f"更新关键词缓存: {self.cached_keywords}")
|
||||||
|
|
||||||
#调用记忆系统获取相关记忆
|
# 调用记忆系统获取相关记忆
|
||||||
related_memory = await HippocampusManager.get_instance().get_memory_from_topic(
|
related_memory = await HippocampusManager.get_instance().get_memory_from_topic(
|
||||||
valid_keywords=keywords, max_memory_num=3, max_memory_length=2, max_depth=3
|
valid_keywords=keywords, max_memory_num=3, max_memory_length=2, max_depth=3
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ class ActionManager:
|
|||||||
# 当前正在使用的动作集合,默认加载默认动作
|
# 当前正在使用的动作集合,默认加载默认动作
|
||||||
self._using_actions: Dict[str, ActionInfo] = {}
|
self._using_actions: Dict[str, ActionInfo] = {}
|
||||||
|
|
||||||
|
|
||||||
# 默认动作集,仅作为快照,用于恢复默认
|
# 默认动作集,仅作为快照,用于恢复默认
|
||||||
self._default_actions: Dict[str, ActionInfo] = {}
|
self._default_actions: Dict[str, ActionInfo] = {}
|
||||||
|
|
||||||
@@ -159,9 +158,9 @@ class ActionManager:
|
|||||||
Optional[BaseAction]: 创建的动作处理器实例,如果动作名称未注册则返回None
|
Optional[BaseAction]: 创建的动作处理器实例,如果动作名称未注册则返回None
|
||||||
"""
|
"""
|
||||||
# 检查动作是否在当前使用的动作集中
|
# 检查动作是否在当前使用的动作集中
|
||||||
if action_name not in self._using_actions:
|
# if action_name not in self._using_actions:
|
||||||
logger.warning(f"当前不可用的动作类型: {action_name}")
|
# logger.warning(f"当前不可用的动作类型: {action_name}")
|
||||||
return None
|
# return None
|
||||||
|
|
||||||
handler_class = _ACTION_REGISTRY.get(action_name)
|
handler_class = _ACTION_REGISTRY.get(action_name)
|
||||||
if not handler_class:
|
if not handler_class:
|
||||||
@@ -283,7 +282,9 @@ class ActionManager:
|
|||||||
|
|
||||||
def restore_actions(self) -> None:
|
def restore_actions(self) -> None:
|
||||||
"""恢复到默认动作集"""
|
"""恢复到默认动作集"""
|
||||||
logger.debug(f"恢复动作集: 从 {list(self._using_actions.keys())} 恢复到默认动作集 {list(self._default_actions.keys())}")
|
logger.debug(
|
||||||
|
f"恢复动作集: 从 {list(self._using_actions.keys())} 恢复到默认动作集 {list(self._default_actions.keys())}"
|
||||||
|
)
|
||||||
self._using_actions = self._default_actions.copy()
|
self._using_actions = self._default_actions.copy()
|
||||||
|
|
||||||
def restore_default_actions(self) -> None:
|
def restore_default_actions(self) -> None:
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
# 导入所有动作模块以确保装饰器被执行
|
# 导入所有动作模块以确保装饰器被执行
|
||||||
from . import reply_action # noqa
|
from . import reply_action # noqa
|
||||||
from . import no_reply_action # noqa
|
from . import no_reply_action # noqa
|
||||||
|
from . import exit_focus_chat_action # noqa
|
||||||
|
|
||||||
# 在此处添加更多动作模块导入
|
# 在此处添加更多动作模块导入
|
||||||
|
|||||||
@@ -5,8 +5,6 @@ from src.chat.focus_chat.planners.actions.base_action import BaseAction, registe
|
|||||||
from typing import Tuple, List
|
from typing import Tuple, List
|
||||||
from src.chat.heart_flow.observation.observation import Observation
|
from src.chat.heart_flow.observation.observation import Observation
|
||||||
from src.chat.message_receive.chat_stream import ChatStream
|
from src.chat.message_receive.chat_stream import ChatStream
|
||||||
from src.chat.heart_flow.heartflow import heartflow
|
|
||||||
from src.chat.heart_flow.sub_heartflow import ChatState
|
|
||||||
|
|
||||||
logger = get_logger("action_taken")
|
logger = get_logger("action_taken")
|
||||||
|
|
||||||
@@ -27,7 +25,7 @@ class ExitFocusChatAction(BaseAction):
|
|||||||
"当前内容不需要持续专注关注,你决定退出专注聊天",
|
"当前内容不需要持续专注关注,你决定退出专注聊天",
|
||||||
"聊天内容已经完成,你决定退出专注聊天",
|
"聊天内容已经完成,你决定退出专注聊天",
|
||||||
]
|
]
|
||||||
default = True
|
default = False
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
@@ -56,7 +54,6 @@ class ExitFocusChatAction(BaseAction):
|
|||||||
self.observations = observations
|
self.observations = observations
|
||||||
self.log_prefix = log_prefix
|
self.log_prefix = log_prefix
|
||||||
self._shutting_down = shutting_down
|
self._shutting_down = shutting_down
|
||||||
self.chat_id = chat_stream.stream_id
|
|
||||||
|
|
||||||
async def handle_action(self) -> Tuple[bool, str]:
|
async def handle_action(self) -> Tuple[bool, str]:
|
||||||
"""
|
"""
|
||||||
@@ -74,23 +71,8 @@ class ExitFocusChatAction(BaseAction):
|
|||||||
try:
|
try:
|
||||||
# 转换状态
|
# 转换状态
|
||||||
status_message = ""
|
status_message = ""
|
||||||
self.sub_heartflow = await heartflow.get_or_create_subheartflow(self.chat_id)
|
command = "stop_focus_chat"
|
||||||
if self.sub_heartflow:
|
return True, status_message, command
|
||||||
try:
|
|
||||||
# 转换为normal_chat状态
|
|
||||||
await self.sub_heartflow.change_chat_state(ChatState.CHAT)
|
|
||||||
status_message = "已成功切换到普通聊天模式"
|
|
||||||
logger.info(f"{self.log_prefix} {status_message}")
|
|
||||||
except Exception as e:
|
|
||||||
error_msg = f"切换到普通聊天模式失败: {str(e)}"
|
|
||||||
logger.error(f"{self.log_prefix} {error_msg}")
|
|
||||||
return False, error_msg
|
|
||||||
else:
|
|
||||||
warning_msg = "未找到有效的sub heartflow实例,无法切换状态"
|
|
||||||
logger.warning(f"{self.log_prefix} {warning_msg}")
|
|
||||||
return False, warning_msg
|
|
||||||
|
|
||||||
return True, status_message
|
|
||||||
|
|
||||||
except asyncio.CancelledError:
|
except asyncio.CancelledError:
|
||||||
logger.info(f"{self.log_prefix} 处理 'exit_focus_chat' 时等待被中断 (CancelledError)")
|
logger.info(f"{self.log_prefix} 处理 'exit_focus_chat' 时等待被中断 (CancelledError)")
|
||||||
@@ -99,4 +81,4 @@ class ExitFocusChatAction(BaseAction):
|
|||||||
error_msg = f"处理 'exit_focus_chat' 时发生错误: {str(e)}"
|
error_msg = f"处理 'exit_focus_chat' 时发生错误: {str(e)}"
|
||||||
logger.error(f"{self.log_prefix} {error_msg}")
|
logger.error(f"{self.log_prefix} {error_msg}")
|
||||||
logger.error(traceback.format_exc())
|
logger.error(traceback.format_exc())
|
||||||
return False, error_msg
|
return False, "", ""
|
||||||
|
|||||||
@@ -156,7 +156,7 @@ class ActionPlanner:
|
|||||||
logger.info(f"{self.log_prefix}{reasoning}")
|
logger.info(f"{self.log_prefix}{reasoning}")
|
||||||
self.action_manager.restore_actions()
|
self.action_manager.restore_actions()
|
||||||
logger.debug(
|
logger.debug(
|
||||||
f"{self.log_prefix}恢复到默认动作集, 当前可用: {list(self.action_manager.get_using_actions().keys())}"
|
f"{self.log_prefix}沉默后恢复到默认动作集, 当前可用: {list(self.action_manager.get_using_actions().keys())}"
|
||||||
)
|
)
|
||||||
return {
|
return {
|
||||||
"action_result": {"action_type": action, "action_data": action_data, "reasoning": reasoning},
|
"action_result": {"action_type": action, "action_data": action_data, "reasoning": reasoning},
|
||||||
@@ -241,7 +241,7 @@ class ActionPlanner:
|
|||||||
# 恢复到默认动作集
|
# 恢复到默认动作集
|
||||||
self.action_manager.restore_actions()
|
self.action_manager.restore_actions()
|
||||||
logger.debug(
|
logger.debug(
|
||||||
f"{self.log_prefix}恢复到默认动作集, 当前可用: {list(self.action_manager.get_using_actions().keys())}"
|
f"{self.log_prefix}规划后恢复到默认动作集, 当前可用: {list(self.action_manager.get_using_actions().keys())}"
|
||||||
)
|
)
|
||||||
|
|
||||||
action_result = {"action_type": action, "action_data": action_data, "reasoning": reasoning}
|
action_result = {"action_type": action, "action_data": action_data, "reasoning": reasoning}
|
||||||
|
|||||||
@@ -33,7 +33,10 @@ class MemoryManager:
|
|||||||
self._id_map: Dict[str, MemoryItem] = {}
|
self._id_map: Dict[str, MemoryItem] = {}
|
||||||
|
|
||||||
self.llm_summarizer = LLMRequest(
|
self.llm_summarizer = LLMRequest(
|
||||||
model=global_config.model.focus_working_memory, temperature=0.3, max_tokens=512, request_type="memory_summarization"
|
model=global_config.model.focus_working_memory,
|
||||||
|
temperature=0.3,
|
||||||
|
max_tokens=512,
|
||||||
|
request_type="memory_summarization",
|
||||||
)
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|||||||
@@ -92,28 +92,30 @@ class BackgroundTaskManager:
|
|||||||
|
|
||||||
# 根据 chat_mode 条件添加其他任务
|
# 根据 chat_mode 条件添加其他任务
|
||||||
if not (global_config.chat.chat_mode == "normal"):
|
if not (global_config.chat.chat_mode == "normal"):
|
||||||
task_configs.extend([
|
task_configs.extend(
|
||||||
(
|
[
|
||||||
self._run_cleanup_cycle,
|
(
|
||||||
"info",
|
self._run_cleanup_cycle,
|
||||||
f"清理任务已启动 间隔:{CLEANUP_INTERVAL_SECONDS}s",
|
"info",
|
||||||
"_cleanup_task",
|
f"清理任务已启动 间隔:{CLEANUP_INTERVAL_SECONDS}s",
|
||||||
),
|
"_cleanup_task",
|
||||||
# 新增私聊激活任务配置
|
),
|
||||||
(
|
# 新增私聊激活任务配置
|
||||||
# Use lambda to pass the interval to the runner function
|
(
|
||||||
lambda: self._run_private_chat_activation_cycle(PRIVATE_CHAT_ACTIVATION_CHECK_INTERVAL_SECONDS),
|
# Use lambda to pass the interval to the runner function
|
||||||
"debug",
|
lambda: self._run_private_chat_activation_cycle(PRIVATE_CHAT_ACTIVATION_CHECK_INTERVAL_SECONDS),
|
||||||
f"私聊激活检查任务已启动 间隔:{PRIVATE_CHAT_ACTIVATION_CHECK_INTERVAL_SECONDS}s",
|
"debug",
|
||||||
"_private_chat_activation_task",
|
f"私聊激活检查任务已启动 间隔:{PRIVATE_CHAT_ACTIVATION_CHECK_INTERVAL_SECONDS}s",
|
||||||
),
|
"_private_chat_activation_task",
|
||||||
# (
|
),
|
||||||
# self._run_into_focus_cycle,
|
# (
|
||||||
# "debug", # 设为debug,避免过多日志
|
# self._run_into_focus_cycle,
|
||||||
# f"专注评估任务已启动 间隔:{INTEREST_EVAL_INTERVAL_SECONDS}s",
|
# "debug", # 设为debug,避免过多日志
|
||||||
# "_into_focus_task",
|
# f"专注评估任务已启动 间隔:{INTEREST_EVAL_INTERVAL_SECONDS}s",
|
||||||
# )
|
# "_into_focus_task",
|
||||||
])
|
# )
|
||||||
|
]
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
logger.info("聊天模式为 normal,跳过启动清理任务、私聊激活任务和专注评估任务")
|
logger.info("聊天模式为 normal,跳过启动清理任务、私聊激活任务和专注评估任务")
|
||||||
|
|
||||||
|
|||||||
@@ -59,11 +59,11 @@ class Heartflow:
|
|||||||
|
|
||||||
async def api_get_normal_chat_replies(self, subheartflow_id: str, limit: int = 10) -> Optional[List[dict]]:
|
async def api_get_normal_chat_replies(self, subheartflow_id: str, limit: int = 10) -> Optional[List[dict]]:
|
||||||
"""获取子心流的NormalChat回复记录
|
"""获取子心流的NormalChat回复记录
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
subheartflow_id: 子心流ID
|
subheartflow_id: 子心流ID
|
||||||
limit: 最大返回数量,默认10条
|
limit: 最大返回数量,默认10条
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Optional[List[dict]]: 回复记录列表,如果子心流不存在则返回None
|
Optional[List[dict]]: 回复记录列表,如果子心流不存在则返回None
|
||||||
"""
|
"""
|
||||||
@@ -71,7 +71,7 @@ class Heartflow:
|
|||||||
if not subheartflow:
|
if not subheartflow:
|
||||||
logger.warning(f"尝试获取不存在的子心流 {subheartflow_id} 的NormalChat回复记录")
|
logger.warning(f"尝试获取不存在的子心流 {subheartflow_id} 的NormalChat回复记录")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
return subheartflow.get_normal_chat_recent_replies(limit)
|
return subheartflow.get_normal_chat_recent_replies(limit)
|
||||||
|
|
||||||
async def heartflow_start_working(self):
|
async def heartflow_start_working(self):
|
||||||
|
|||||||
@@ -20,9 +20,9 @@ MAX_REPLY_PROBABILITY = 1
|
|||||||
class InterestChatting:
|
class InterestChatting:
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
decay_rate=global_config.focus_chat.default_decay_rate_per_second,
|
decay_rate=0.95,
|
||||||
max_interest=MAX_INTEREST,
|
max_interest=MAX_INTEREST,
|
||||||
trigger_threshold=global_config.focus_chat.reply_trigger_threshold,
|
trigger_threshold=4,
|
||||||
max_probability=MAX_REPLY_PROBABILITY,
|
max_probability=MAX_REPLY_PROBABILITY,
|
||||||
):
|
):
|
||||||
# 基础属性初始化
|
# 基础属性初始化
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from src.llm_models.utils_model import LLMRequest
|
|
||||||
from src.config.config import global_config
|
from src.config.config import global_config
|
||||||
import traceback
|
import traceback
|
||||||
from src.chat.utils.chat_message_builder import (
|
from src.chat.utils.chat_message_builder import (
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ from src.chat.normal_chat.normal_chat import NormalChat
|
|||||||
from src.chat.heart_flow.mai_state_manager import MaiStateInfo
|
from src.chat.heart_flow.mai_state_manager import MaiStateInfo
|
||||||
from src.chat.heart_flow.chat_state_info import ChatState, ChatStateInfo
|
from src.chat.heart_flow.chat_state_info import ChatState, ChatStateInfo
|
||||||
from .utils_chat import get_chat_type_and_target_info
|
from .utils_chat import get_chat_type_and_target_info
|
||||||
from .interest_chatting import InterestChatting
|
|
||||||
from src.config.config import global_config
|
from src.config.config import global_config
|
||||||
|
|
||||||
|
|
||||||
@@ -51,7 +50,7 @@ class SubHeartflow:
|
|||||||
# --- End Initialization ---
|
# --- End Initialization ---
|
||||||
|
|
||||||
# 兴趣检测器
|
# 兴趣检测器
|
||||||
self.interest_chatting: InterestChatting = InterestChatting()
|
self.interest_dict: Dict[str, tuple[MessageRecv, float, bool]] = {}
|
||||||
|
|
||||||
# 活动状态管理
|
# 活动状态管理
|
||||||
self.should_stop = False # 停止标志
|
self.should_stop = False # 停止标志
|
||||||
@@ -85,8 +84,8 @@ class SubHeartflow:
|
|||||||
# --- End using utility function ---
|
# --- End using utility function ---
|
||||||
|
|
||||||
# Initialize interest system (existing logic)
|
# Initialize interest system (existing logic)
|
||||||
await self.interest_chatting.initialize()
|
# await self.interest_chatting.initialize()
|
||||||
logger.debug(f"{self.log_prefix} InterestChatting 实例已初始化。")
|
# logger.debug(f"{self.log_prefix} InterestChatting 实例已初始化。")
|
||||||
|
|
||||||
# 根据配置决定初始状态
|
# 根据配置决定初始状态
|
||||||
if global_config.chat.chat_mode == "focus":
|
if global_config.chat.chat_mode == "focus":
|
||||||
@@ -131,9 +130,9 @@ class SubHeartflow:
|
|||||||
if rewind or not self.normal_chat_instance:
|
if rewind or not self.normal_chat_instance:
|
||||||
# 提供回调函数,用于接收需要切换到focus模式的通知
|
# 提供回调函数,用于接收需要切换到focus模式的通知
|
||||||
self.normal_chat_instance = NormalChat(
|
self.normal_chat_instance = NormalChat(
|
||||||
chat_stream=chat_stream,
|
chat_stream=chat_stream,
|
||||||
interest_dict=self.get_interest_dict(),
|
interest_dict=self.interest_dict,
|
||||||
on_switch_to_focus_callback=self._handle_switch_to_focus_request
|
on_switch_to_focus_callback=self._handle_switch_to_focus_request,
|
||||||
)
|
)
|
||||||
|
|
||||||
# 进行异步初始化
|
# 进行异步初始化
|
||||||
@@ -152,12 +151,12 @@ class SubHeartflow:
|
|||||||
async def _handle_switch_to_focus_request(self) -> None:
|
async def _handle_switch_to_focus_request(self) -> None:
|
||||||
"""
|
"""
|
||||||
处理来自NormalChat的切换到focus模式的请求
|
处理来自NormalChat的切换到focus模式的请求
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
stream_id: 请求切换的stream_id
|
stream_id: 请求切换的stream_id
|
||||||
"""
|
"""
|
||||||
logger.info(f"{self.log_prefix} 收到NormalChat请求切换到focus模式")
|
logger.info(f"{self.log_prefix} 收到NormalChat请求切换到focus模式")
|
||||||
|
|
||||||
# 切换到focus模式
|
# 切换到focus模式
|
||||||
current_state = self.chat_state.chat_status
|
current_state = self.chat_state.chat_status
|
||||||
if current_state == ChatState.NORMAL:
|
if current_state == ChatState.NORMAL:
|
||||||
@@ -166,6 +165,21 @@ class SubHeartflow:
|
|||||||
else:
|
else:
|
||||||
logger.warning(f"{self.log_prefix} 当前状态为{current_state.value},无法切换到FOCUSED状态")
|
logger.warning(f"{self.log_prefix} 当前状态为{current_state.value},无法切换到FOCUSED状态")
|
||||||
|
|
||||||
|
async def _handle_stop_focus_chat_request(self) -> None:
|
||||||
|
"""
|
||||||
|
处理来自HeartFChatting的停止focus模式的请求
|
||||||
|
当收到stop_focus_chat命令时被调用
|
||||||
|
"""
|
||||||
|
logger.info(f"{self.log_prefix} 收到HeartFChatting请求停止focus模式")
|
||||||
|
|
||||||
|
# 切换到normal模式
|
||||||
|
current_state = self.chat_state.chat_status
|
||||||
|
if current_state == ChatState.FOCUSED:
|
||||||
|
await self.change_chat_state(ChatState.NORMAL)
|
||||||
|
logger.info(f"{self.log_prefix} 已根据HeartFChatting请求从FOCUSED切换到NORMAL状态")
|
||||||
|
else:
|
||||||
|
logger.warning(f"{self.log_prefix} 当前状态为{current_state.value},无法切换到NORMAL状态")
|
||||||
|
|
||||||
async def _stop_heart_fc_chat(self):
|
async def _stop_heart_fc_chat(self):
|
||||||
"""停止并清理 HeartFChatting 实例"""
|
"""停止并清理 HeartFChatting 实例"""
|
||||||
if self.heart_fc_instance:
|
if self.heart_fc_instance:
|
||||||
@@ -182,7 +196,7 @@ class SubHeartflow:
|
|||||||
async def _start_heart_fc_chat(self) -> bool:
|
async def _start_heart_fc_chat(self) -> bool:
|
||||||
"""启动 HeartFChatting 实例,确保 NormalChat 已停止"""
|
"""启动 HeartFChatting 实例,确保 NormalChat 已停止"""
|
||||||
await self._stop_normal_chat() # 确保普通聊天监控已停止
|
await self._stop_normal_chat() # 确保普通聊天监控已停止
|
||||||
self.clear_interest_dict() # 清理兴趣字典,准备专注聊天
|
self.interest_dict.clear()
|
||||||
|
|
||||||
log_prefix = self.log_prefix
|
log_prefix = self.log_prefix
|
||||||
# 如果实例已存在,检查其循环任务状态
|
# 如果实例已存在,检查其循环任务状态
|
||||||
@@ -211,6 +225,7 @@ class SubHeartflow:
|
|||||||
self.heart_fc_instance = HeartFChatting(
|
self.heart_fc_instance = HeartFChatting(
|
||||||
chat_id=self.subheartflow_id,
|
chat_id=self.subheartflow_id,
|
||||||
observations=self.observations,
|
observations=self.observations,
|
||||||
|
on_stop_focus_chat=self._handle_stop_focus_chat_request,
|
||||||
)
|
)
|
||||||
|
|
||||||
# 初始化并启动 HeartFChatting
|
# 初始化并启动 HeartFChatting
|
||||||
@@ -259,7 +274,7 @@ class SubHeartflow:
|
|||||||
|
|
||||||
elif new_state == ChatState.ABSENT:
|
elif new_state == ChatState.ABSENT:
|
||||||
logger.info(f"{log_prefix} 进入 ABSENT 状态,停止所有聊天活动...")
|
logger.info(f"{log_prefix} 进入 ABSENT 状态,停止所有聊天活动...")
|
||||||
self.clear_interest_dict()
|
self.interest_dict.clear()
|
||||||
await self._stop_normal_chat()
|
await self._stop_normal_chat()
|
||||||
await self._stop_heart_fc_chat()
|
await self._stop_heart_fc_chat()
|
||||||
state_changed = True
|
state_changed = True
|
||||||
@@ -300,38 +315,35 @@ class SubHeartflow:
|
|||||||
logger.warning(f"SubHeartflow {self.subheartflow_id} 没有找到有效的 ChattingObservation")
|
logger.warning(f"SubHeartflow {self.subheartflow_id} 没有找到有效的 ChattingObservation")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
async def get_interest_state(self) -> dict:
|
|
||||||
return await self.interest_chatting.get_state()
|
|
||||||
|
|
||||||
def get_normal_chat_last_speak_time(self) -> float:
|
def get_normal_chat_last_speak_time(self) -> float:
|
||||||
if self.normal_chat_instance:
|
if self.normal_chat_instance:
|
||||||
return self.normal_chat_instance.last_speak_time
|
return self.normal_chat_instance.last_speak_time
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
def get_interest_dict(self) -> Dict[str, tuple[MessageRecv, float, bool]]:
|
|
||||||
return self.interest_chatting.interest_dict
|
|
||||||
|
|
||||||
def get_normal_chat_recent_replies(self, limit: int = 10) -> List[dict]:
|
def get_normal_chat_recent_replies(self, limit: int = 10) -> List[dict]:
|
||||||
"""获取NormalChat实例的最近回复记录
|
"""获取NormalChat实例的最近回复记录
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
limit: 最大返回数量,默认10条
|
limit: 最大返回数量,默认10条
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
List[dict]: 最近的回复记录列表,如果没有NormalChat实例则返回空列表
|
List[dict]: 最近的回复记录列表,如果没有NormalChat实例则返回空列表
|
||||||
"""
|
"""
|
||||||
if self.normal_chat_instance:
|
if self.normal_chat_instance:
|
||||||
return self.normal_chat_instance.get_recent_replies(limit)
|
return self.normal_chat_instance.get_recent_replies(limit)
|
||||||
return []
|
return []
|
||||||
|
|
||||||
def clear_interest_dict(self):
|
def add_interest_message(self, message: MessageRecv, interest_value: float, is_mentioned: bool):
|
||||||
self.interest_chatting.interest_dict.clear()
|
self.interest_dict[message.message_info.message_id] = (message, interest_value, is_mentioned)
|
||||||
|
# 如果字典长度超过10,删除最旧的消息
|
||||||
|
if len(self.interest_dict) > 10:
|
||||||
|
oldest_key = next(iter(self.interest_dict))
|
||||||
|
self.interest_dict.pop(oldest_key)
|
||||||
|
|
||||||
async def get_full_state(self) -> dict:
|
async def get_full_state(self) -> dict:
|
||||||
"""获取子心流的完整状态,包括兴趣、思维和聊天状态。"""
|
"""获取子心流的完整状态,包括兴趣、思维和聊天状态。"""
|
||||||
interest_state = await self.get_interest_state()
|
|
||||||
return {
|
return {
|
||||||
"interest_state": interest_state,
|
"interest_state": "interest_state",
|
||||||
"chat_state": self.chat_state.chat_status.value,
|
"chat_state": self.chat_state.chat_status.value,
|
||||||
"chat_state_changed_time": self.chat_state_changed_time,
|
"chat_state_changed_time": self.chat_state_changed_time,
|
||||||
}
|
}
|
||||||
@@ -349,10 +361,6 @@ class SubHeartflow:
|
|||||||
await self._stop_normal_chat()
|
await self._stop_normal_chat()
|
||||||
await self._stop_heart_fc_chat()
|
await self._stop_heart_fc_chat()
|
||||||
|
|
||||||
# 停止兴趣更新任务
|
|
||||||
if self.interest_chatting:
|
|
||||||
logger.info(f"{self.log_prefix} 停止兴趣系统后台任务...")
|
|
||||||
await self.interest_chatting.stop_updates()
|
|
||||||
|
|
||||||
# 取消可能存在的旧后台任务 (self.task)
|
# 取消可能存在的旧后台任务 (self.task)
|
||||||
if self.task and not self.task.done():
|
if self.task and not self.task.done():
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
import time
|
import time
|
||||||
import random
|
|
||||||
from typing import Dict, Any, Optional, List
|
from typing import Dict, Any, Optional, List
|
||||||
from src.common.logger_manager import get_logger
|
from src.common.logger_manager import get_logger
|
||||||
from src.chat.message_receive.chat_stream import chat_manager
|
from src.chat.message_receive.chat_stream import chat_manager
|
||||||
@@ -187,40 +186,40 @@ class SubHeartflowManager:
|
|||||||
)
|
)
|
||||||
|
|
||||||
# async def sbhf_normal_into_focus(self):
|
# async def sbhf_normal_into_focus(self):
|
||||||
# """评估子心流兴趣度,满足条件则提升到FOCUSED状态(基于start_hfc_probability)"""
|
# """评估子心流兴趣度,满足条件则提升到FOCUSED状态(基于start_hfc_probability)"""
|
||||||
# try:
|
# try:
|
||||||
# for sub_hf in list(self.subheartflows.values()):
|
# for sub_hf in list(self.subheartflows.values()):
|
||||||
# flow_id = sub_hf.subheartflow_id
|
# flow_id = sub_hf.subheartflow_id
|
||||||
# stream_name = chat_manager.get_stream_name(flow_id) or flow_id
|
# stream_name = chat_manager.get_stream_name(flow_id) or flow_id
|
||||||
|
|
||||||
# # 跳过已经是FOCUSED状态的子心流
|
# # 跳过已经是FOCUSED状态的子心流
|
||||||
# if sub_hf.chat_state.chat_status == ChatState.FOCUSED:
|
# if sub_hf.chat_state.chat_status == ChatState.FOCUSED:
|
||||||
# continue
|
# continue
|
||||||
|
|
||||||
# if sub_hf.interest_chatting.start_hfc_probability == 0:
|
# if sub_hf.interest_chatting.start_hfc_probability == 0:
|
||||||
# continue
|
# continue
|
||||||
# else:
|
# else:
|
||||||
# logger.debug(
|
# logger.debug(
|
||||||
# f"{stream_name},现在状态: {sub_hf.chat_state.chat_status.value},进入专注概率: {sub_hf.interest_chatting.start_hfc_probability}"
|
# f"{stream_name},现在状态: {sub_hf.chat_state.chat_status.value},进入专注概率: {sub_hf.interest_chatting.start_hfc_probability}"
|
||||||
# )
|
# )
|
||||||
|
|
||||||
# if random.random() >= sub_hf.interest_chatting.start_hfc_probability:
|
# if random.random() >= sub_hf.interest_chatting.start_hfc_probability:
|
||||||
# continue
|
# continue
|
||||||
|
|
||||||
# # 获取最新状态并执行提升
|
# # 获取最新状态并执行提升
|
||||||
# current_subflow = self.subheartflows.get(flow_id)
|
# current_subflow = self.subheartflows.get(flow_id)
|
||||||
# if not current_subflow:
|
# if not current_subflow:
|
||||||
# continue
|
# continue
|
||||||
|
|
||||||
# logger.info(
|
# logger.info(
|
||||||
# f"{stream_name} 触发 认真水群 (概率={current_subflow.interest_chatting.start_hfc_probability:.2f})"
|
# f"{stream_name} 触发 认真水群 (概率={current_subflow.interest_chatting.start_hfc_probability:.2f})"
|
||||||
# )
|
# )
|
||||||
|
|
||||||
# # 执行状态提升
|
# # 执行状态提升
|
||||||
# await current_subflow.change_chat_state(ChatState.FOCUSED)
|
# await current_subflow.change_chat_state(ChatState.FOCUSED)
|
||||||
|
|
||||||
# except Exception as e:
|
# except Exception as e:
|
||||||
# logger.error(f"启动HFC 兴趣评估失败: {e}", exc_info=True)
|
# logger.error(f"启动HFC 兴趣评估失败: {e}", exc_info=True)
|
||||||
|
|
||||||
async def sbhf_focus_into_normal(self, subflow_id: Any):
|
async def sbhf_focus_into_normal(self, subflow_id: Any):
|
||||||
"""
|
"""
|
||||||
@@ -249,7 +248,7 @@ class SubHeartflowManager:
|
|||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
# 从HFC到CHAT时,清空兴趣字典
|
# 从HFC到CHAT时,清空兴趣字典
|
||||||
subflow.clear_interest_dict()
|
subflow.interest_dict.clear()
|
||||||
await subflow.change_chat_state(target_state)
|
await subflow.change_chat_state(target_state)
|
||||||
final_state = subflow.chat_state.chat_status
|
final_state = subflow.chat_state.chat_status
|
||||||
if final_state == target_state:
|
if final_state == target_state:
|
||||||
|
|||||||
@@ -49,14 +49,14 @@ class NormalChat:
|
|||||||
self.last_speak_time = 0
|
self.last_speak_time = 0
|
||||||
self._chat_task: Optional[asyncio.Task] = None
|
self._chat_task: Optional[asyncio.Task] = None
|
||||||
self._initialized = False # Track initialization status
|
self._initialized = False # Track initialization status
|
||||||
|
|
||||||
# 记录最近的回复内容,每项包含: {time, user_message, response, is_mentioned, is_reference_reply}
|
# 记录最近的回复内容,每项包含: {time, user_message, response, is_mentioned, is_reference_reply}
|
||||||
self.recent_replies = []
|
self.recent_replies = []
|
||||||
self.max_replies_history = 20 # 最多保存最近20条回复记录
|
self.max_replies_history = 20 # 最多保存最近20条回复记录
|
||||||
|
|
||||||
# 添加回调函数,用于在满足条件时通知切换到focus_chat模式
|
# 添加回调函数,用于在满足条件时通知切换到focus_chat模式
|
||||||
self.on_switch_to_focus_callback = on_switch_to_focus_callback
|
self.on_switch_to_focus_callback = on_switch_to_focus_callback
|
||||||
|
|
||||||
# 最近回复检查相关
|
# 最近回复检查相关
|
||||||
self._last_check_time = time.time()
|
self._last_check_time = time.time()
|
||||||
self._check_interval = 10 # 每10秒检查一次是否需要切换到focus模式
|
self._check_interval = 10 # 每10秒检查一次是否需要切换到focus模式
|
||||||
@@ -207,12 +207,12 @@ class NormalChat:
|
|||||||
if self._chat_task is None or self._chat_task.cancelled():
|
if self._chat_task is None or self._chat_task.cancelled():
|
||||||
logger.info(f"[{self.stream_name}] 兴趣监控任务被取消或置空,退出")
|
logger.info(f"[{self.stream_name}] 兴趣监控任务被取消或置空,退出")
|
||||||
break
|
break
|
||||||
|
|
||||||
# 定期检查是否需要切换到focus模式
|
# 定期检查是否需要切换到focus模式
|
||||||
current_time = time.time()
|
# current_time = time.time()
|
||||||
if current_time - self._last_check_time > self._check_interval:
|
# if current_time - self._last_check_time > self._check_interval:
|
||||||
await self._check_switch_to_focus()
|
# await self._check_switch_to_focus()
|
||||||
self._last_check_time = current_time
|
# self._last_check_time = current_time
|
||||||
|
|
||||||
items_to_process = list(self.interest_dict.items())
|
items_to_process = list(self.interest_dict.items())
|
||||||
if not items_to_process:
|
if not items_to_process:
|
||||||
@@ -329,28 +329,28 @@ class NormalChat:
|
|||||||
# 检查 first_bot_msg 是否为 None (例如思考消息已被移除的情况)
|
# 检查 first_bot_msg 是否为 None (例如思考消息已被移除的情况)
|
||||||
if first_bot_msg:
|
if first_bot_msg:
|
||||||
info_catcher.catch_after_response(timing_results["消息发送"], response_set, first_bot_msg)
|
info_catcher.catch_after_response(timing_results["消息发送"], response_set, first_bot_msg)
|
||||||
|
|
||||||
# 记录回复信息到最近回复列表中
|
# 记录回复信息到最近回复列表中
|
||||||
reply_info = {
|
reply_info = {
|
||||||
"time": time.time(),
|
"time": time.time(),
|
||||||
"user_message": message.processed_plain_text,
|
"user_message": message.processed_plain_text,
|
||||||
"user_info": {
|
"user_info": {
|
||||||
"user_id": message.message_info.user_info.user_id,
|
"user_id": message.message_info.user_info.user_id,
|
||||||
"user_nickname": message.message_info.user_info.user_nickname
|
"user_nickname": message.message_info.user_info.user_nickname,
|
||||||
},
|
},
|
||||||
"response": response_set,
|
"response": response_set,
|
||||||
"is_mentioned": is_mentioned,
|
"is_mentioned": is_mentioned,
|
||||||
"is_reference_reply": message.reply is not None, # 判断是否为引用回复
|
"is_reference_reply": message.reply is not None, # 判断是否为引用回复
|
||||||
"timing": {k: round(v, 2) for k, v in timing_results.items()}
|
"timing": {k: round(v, 2) for k, v in timing_results.items()},
|
||||||
}
|
}
|
||||||
self.recent_replies.append(reply_info)
|
self.recent_replies.append(reply_info)
|
||||||
# 保持最近回复历史在限定数量内
|
# 保持最近回复历史在限定数量内
|
||||||
if len(self.recent_replies) > self.max_replies_history:
|
if len(self.recent_replies) > self.max_replies_history:
|
||||||
self.recent_replies = self.recent_replies[-self.max_replies_history:]
|
self.recent_replies = self.recent_replies[-self.max_replies_history :]
|
||||||
|
|
||||||
# 检查是否需要切换到focus模式
|
# 检查是否需要切换到focus模式
|
||||||
await self._check_switch_to_focus()
|
await self._check_switch_to_focus()
|
||||||
|
|
||||||
else:
|
else:
|
||||||
logger.warning(f"[{self.stream_name}] 思考消息 {thinking_id} 在发送前丢失,无法记录 info_catcher")
|
logger.warning(f"[{self.stream_name}] 思考消息 {thinking_id} 在发送前丢失,无法记录 info_catcher")
|
||||||
|
|
||||||
@@ -563,10 +563,10 @@ class NormalChat:
|
|||||||
# 获取最近回复记录的方法
|
# 获取最近回复记录的方法
|
||||||
def get_recent_replies(self, limit: int = 10) -> List[dict]:
|
def get_recent_replies(self, limit: int = 10) -> List[dict]:
|
||||||
"""获取最近的回复记录
|
"""获取最近的回复记录
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
limit: 最大返回数量,默认10条
|
limit: 最大返回数量,默认10条
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
List[dict]: 最近的回复记录列表,每项包含:
|
List[dict]: 最近的回复记录列表,每项包含:
|
||||||
time: 回复时间戳
|
time: 回复时间戳
|
||||||
@@ -583,21 +583,23 @@ class NormalChat:
|
|||||||
async def _check_switch_to_focus(self) -> None:
|
async def _check_switch_to_focus(self) -> None:
|
||||||
"""检查是否满足切换到focus模式的条件"""
|
"""检查是否满足切换到focus模式的条件"""
|
||||||
if not self.on_switch_to_focus_callback:
|
if not self.on_switch_to_focus_callback:
|
||||||
return # 如果没有设置回调函数,直接返回
|
return # 如果没有设置回调函数,直接返回
|
||||||
current_time = time.time()
|
current_time = time.time()
|
||||||
|
|
||||||
time_threshold = 120 / global_config.focus_chat.auto_focus_threshold
|
time_threshold = 120 / global_config.focus_chat.auto_focus_threshold
|
||||||
reply_threshold = 6 * global_config.focus_chat.auto_focus_threshold
|
reply_threshold = 6 * global_config.focus_chat.auto_focus_threshold
|
||||||
|
|
||||||
one_minute_ago = current_time - time_threshold
|
one_minute_ago = current_time - time_threshold
|
||||||
|
|
||||||
# 统计1分钟内的回复数量
|
# 统计1分钟内的回复数量
|
||||||
recent_reply_count = sum(1 for reply in self.recent_replies if reply["time"] > one_minute_ago)
|
recent_reply_count = sum(1 for reply in self.recent_replies if reply["time"] > one_minute_ago)
|
||||||
# print(111111111111111333333333333333333333333331111111111111111111111111111111111)
|
# print(111111111111111333333333333333333333333331111111111111111111111111111111111)
|
||||||
# print(recent_reply_count)
|
# print(recent_reply_count)
|
||||||
# 如果1分钟内回复数量大于8,触发切换到focus模式
|
# 如果1分钟内回复数量大于8,触发切换到focus模式
|
||||||
if recent_reply_count > reply_threshold:
|
if recent_reply_count > reply_threshold:
|
||||||
logger.info(f"[{self.stream_name}] 检测到1分钟内回复数量({recent_reply_count})大于{reply_threshold},触发切换到focus模式")
|
logger.info(
|
||||||
|
f"[{self.stream_name}] 检测到1分钟内回复数量({recent_reply_count})大于{reply_threshold},触发切换到focus模式"
|
||||||
|
)
|
||||||
try:
|
try:
|
||||||
# 调用回调函数通知上层切换到focus模式
|
# 调用回调函数通知上层切换到focus模式
|
||||||
await self.on_switch_to_focus_callback()
|
await self.on_switch_to_focus_callback()
|
||||||
|
|||||||
@@ -44,12 +44,13 @@ class IdentityConfig(ConfigBase):
|
|||||||
identity_detail: list[str] = field(default_factory=lambda: [])
|
identity_detail: list[str] = field(default_factory=lambda: [])
|
||||||
"""身份特征"""
|
"""身份特征"""
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class RelationshipConfig(ConfigBase):
|
class RelationshipConfig(ConfigBase):
|
||||||
"""关系配置类"""
|
"""关系配置类"""
|
||||||
|
|
||||||
give_name: bool = False
|
give_name: bool = False
|
||||||
"""是否给其他人取名"""
|
"""是否给其他人取名"""
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
@@ -125,6 +126,9 @@ class FocusChatConfig(ConfigBase):
|
|||||||
auto_focus_threshold: float = 1.0
|
auto_focus_threshold: float = 1.0
|
||||||
"""自动切换到专注聊天的阈值,越低越容易进入专注聊天"""
|
"""自动切换到专注聊天的阈值,越低越容易进入专注聊天"""
|
||||||
|
|
||||||
|
exit_focus_threshold: float = 1.0
|
||||||
|
"""自动退出专注聊天的阈值,越低越容易退出专注聊天"""
|
||||||
|
|
||||||
observation_context_size: int = 12
|
observation_context_size: int = 12
|
||||||
"""可观察到的最长上下文大小,超过这个值的上下文会被压缩"""
|
"""可观察到的最长上下文大小,超过这个值的上下文会被压缩"""
|
||||||
|
|
||||||
@@ -381,17 +385,16 @@ class ModelConfig(ConfigBase):
|
|||||||
"""模型配置类"""
|
"""模型配置类"""
|
||||||
|
|
||||||
model_max_output_length: int = 800 # 最大回复长度
|
model_max_output_length: int = 800 # 最大回复长度
|
||||||
|
|
||||||
|
|
||||||
utils: dict[str, Any] = field(default_factory=lambda: {})
|
utils: dict[str, Any] = field(default_factory=lambda: {})
|
||||||
"""组件模型配置"""
|
"""组件模型配置"""
|
||||||
|
|
||||||
utils_small: dict[str, Any] = field(default_factory=lambda: {})
|
utils_small: dict[str, Any] = field(default_factory=lambda: {})
|
||||||
"""组件小模型配置"""
|
"""组件小模型配置"""
|
||||||
|
|
||||||
normal_chat_1: dict[str, Any] = field(default_factory=lambda: {})
|
normal_chat_1: dict[str, Any] = field(default_factory=lambda: {})
|
||||||
"""normal_chat首要回复模型模型配置"""
|
"""normal_chat首要回复模型模型配置"""
|
||||||
|
|
||||||
normal_chat_2: dict[str, Any] = field(default_factory=lambda: {})
|
normal_chat_2: dict[str, Any] = field(default_factory=lambda: {})
|
||||||
"""normal_chat次要回复模型配置"""
|
"""normal_chat次要回复模型配置"""
|
||||||
|
|
||||||
@@ -403,22 +406,22 @@ class ModelConfig(ConfigBase):
|
|||||||
|
|
||||||
focus_working_memory: dict[str, Any] = field(default_factory=lambda: {})
|
focus_working_memory: dict[str, Any] = field(default_factory=lambda: {})
|
||||||
"""专注工作记忆模型配置"""
|
"""专注工作记忆模型配置"""
|
||||||
|
|
||||||
focus_chat_mind: dict[str, Any] = field(default_factory=lambda: {})
|
focus_chat_mind: dict[str, Any] = field(default_factory=lambda: {})
|
||||||
"""专注聊天规划模型配置"""
|
"""专注聊天规划模型配置"""
|
||||||
|
|
||||||
focus_self_recognize: dict[str, Any] = field(default_factory=lambda: {})
|
focus_self_recognize: dict[str, Any] = field(default_factory=lambda: {})
|
||||||
"""专注自我识别模型配置"""
|
"""专注自我识别模型配置"""
|
||||||
|
|
||||||
focus_tool_use: dict[str, Any] = field(default_factory=lambda: {})
|
focus_tool_use: dict[str, Any] = field(default_factory=lambda: {})
|
||||||
"""专注工具使用模型配置"""
|
"""专注工具使用模型配置"""
|
||||||
|
|
||||||
focus_planner: dict[str, Any] = field(default_factory=lambda: {})
|
focus_planner: dict[str, Any] = field(default_factory=lambda: {})
|
||||||
"""专注规划模型配置"""
|
"""专注规划模型配置"""
|
||||||
|
|
||||||
focus_expressor: dict[str, Any] = field(default_factory=lambda: {})
|
focus_expressor: dict[str, Any] = field(default_factory=lambda: {})
|
||||||
"""专注表达器模型配置"""
|
"""专注表达器模型配置"""
|
||||||
|
|
||||||
embedding: dict[str, Any] = field(default_factory=lambda: {})
|
embedding: dict[str, Any] = field(default_factory=lambda: {})
|
||||||
"""嵌入模型配置"""
|
"""嵌入模型配置"""
|
||||||
|
|
||||||
@@ -430,7 +433,3 @@ class ModelConfig(ConfigBase):
|
|||||||
|
|
||||||
pfc_reply_checker: dict[str, Any] = field(default_factory=lambda: {})
|
pfc_reply_checker: dict[str, Any] = field(default_factory=lambda: {})
|
||||||
"""PFC回复检查模型配置"""
|
"""PFC回复检查模型配置"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -636,18 +636,18 @@ class LLMRequest:
|
|||||||
"messages": messages,
|
"messages": messages,
|
||||||
**params_copy,
|
**params_copy,
|
||||||
}
|
}
|
||||||
|
|
||||||
# 添加temp参数(如果不是默认值0.7)
|
# 添加temp参数(如果不是默认值0.7)
|
||||||
if self.temp != 0.7:
|
if self.temp != 0.7:
|
||||||
payload["temperature"] = self.temp
|
payload["temperature"] = self.temp
|
||||||
|
|
||||||
# 添加enable_thinking参数(如果不是默认值False)
|
# 添加enable_thinking参数(如果不是默认值False)
|
||||||
if not self.enable_thinking:
|
if not self.enable_thinking:
|
||||||
payload["enable_thinking"] = False
|
payload["enable_thinking"] = False
|
||||||
|
|
||||||
if self.thinking_budget != 4096:
|
if self.thinking_budget != 4096:
|
||||||
payload["thinking_budget"] = self.thinking_budget
|
payload["thinking_budget"] = self.thinking_budget
|
||||||
|
|
||||||
if "max_tokens" not in payload and "max_completion_tokens" not in payload:
|
if "max_tokens" not in payload and "max_completion_tokens" not in payload:
|
||||||
payload["max_tokens"] = global_config.model.model_max_output_length
|
payload["max_tokens"] = global_config.model.model_max_output_length
|
||||||
# 如果 payload 中依然存在 max_tokens 且需要转换,在这里进行再次检查
|
# 如果 payload 中依然存在 max_tokens 且需要转换,在这里进行再次检查
|
||||||
|
|||||||
@@ -261,7 +261,7 @@ class PersonInfoManager:
|
|||||||
current_name_set = set(self.person_name_list.values())
|
current_name_set = set(self.person_name_list.values())
|
||||||
|
|
||||||
while current_try < max_retries:
|
while current_try < max_retries:
|
||||||
prompt_personality = individuality.get_prompt(x_person=2, level=1)
|
# prompt_personality = individuality.get_prompt(x_person=2, level=1)
|
||||||
bot_name = individuality.personality.bot_nickname
|
bot_name = individuality.personality.bot_nickname
|
||||||
|
|
||||||
qv_name_prompt = f"你是{bot_name},一个伪装成人类的AI,你不能让别人发现这一点,"
|
qv_name_prompt = f"你是{bot_name},一个伪装成人类的AI,你不能让别人发现这一点,"
|
||||||
@@ -273,9 +273,7 @@ class PersonInfoManager:
|
|||||||
qv_name_prompt += f"你之前叫他{old_name},是因为{old_reason},"
|
qv_name_prompt += f"你之前叫他{old_name},是因为{old_reason},"
|
||||||
|
|
||||||
qv_name_prompt += f"\n其他取名的要求是:{request},不要太浮夸,简短,"
|
qv_name_prompt += f"\n其他取名的要求是:{request},不要太浮夸,简短,"
|
||||||
qv_name_prompt += (
|
qv_name_prompt += "\n请根据以上用户信息,想想你叫他什么比较好,不要太浮夸,请最好使用用户的qq昵称,可以稍作修改,优先使用原文。优先使用用户的qq昵称或者群昵称原文。"
|
||||||
"\n请根据以上用户信息,想想你叫他什么比较好,不要太浮夸,请最好使用用户的qq昵称,可以稍作修改,优先使用原文。优先使用用户的qq昵称或者群昵称原文。"
|
|
||||||
)
|
|
||||||
|
|
||||||
if existing_names_str:
|
if existing_names_str:
|
||||||
qv_name_prompt += f"\n请注意,以下名称已被你尝试过或已知存在,请避免:{existing_names_str}。\n"
|
qv_name_prompt += f"\n请注意,以下名称已被你尝试过或已知存在,请避免:{existing_names_str}。\n"
|
||||||
|
|||||||
@@ -10,15 +10,13 @@ class GroupWholeBanAction(PluginAction):
|
|||||||
"""群聊全体禁言动作处理类"""
|
"""群聊全体禁言动作处理类"""
|
||||||
|
|
||||||
action_name = "group_whole_ban_action"
|
action_name = "group_whole_ban_action"
|
||||||
action_description = (
|
action_description = "开启或关闭群聊全体禁言,当群聊过于混乱或需要安静时使用"
|
||||||
"开启或关闭群聊全体禁言,当群聊过于混乱或需要安静时使用"
|
|
||||||
)
|
|
||||||
action_parameters = {
|
action_parameters = {
|
||||||
"enable": "是否开启全体禁言,输入True开启,False关闭,必填",
|
"enable": "是否开启全体禁言,输入True开启,False关闭,必填",
|
||||||
}
|
}
|
||||||
action_require = [
|
action_require = [
|
||||||
"当群聊过于混乱需要安静时使用",
|
"当群聊过于混乱需要安静时使用",
|
||||||
"当需要临时暂停群聊讨论时使用",
|
"当需要临时暂停群聊讨论时使用",
|
||||||
"当有人要求开启全体禁言时使用",
|
"当有人要求开启全体禁言时使用",
|
||||||
"当管理员需要发布重要公告时使用",
|
"当管理员需要发布重要公告时使用",
|
||||||
]
|
]
|
||||||
@@ -31,7 +29,7 @@ class GroupWholeBanAction(PluginAction):
|
|||||||
|
|
||||||
# 获取参数
|
# 获取参数
|
||||||
enable = self.action_data.get("enable")
|
enable = self.action_data.get("enable")
|
||||||
|
|
||||||
if enable is None:
|
if enable is None:
|
||||||
error_msg = "全体禁言参数不完整,需要enable参数"
|
error_msg = "全体禁言参数不完整,需要enable参数"
|
||||||
logger.error(f"{self.log_prefix} {error_msg}")
|
logger.error(f"{self.log_prefix} {error_msg}")
|
||||||
@@ -39,9 +37,9 @@ class GroupWholeBanAction(PluginAction):
|
|||||||
|
|
||||||
# 确保enable是布尔类型
|
# 确保enable是布尔类型
|
||||||
if isinstance(enable, str):
|
if isinstance(enable, str):
|
||||||
if enable.lower() in ['true', '1', 'yes', '开启', '是']:
|
if enable.lower() in ["true", "1", "yes", "开启", "是"]:
|
||||||
enable = True
|
enable = True
|
||||||
elif enable.lower() in ['false', '0', 'no', '关闭', '否']:
|
elif enable.lower() in ["false", "0", "no", "关闭", "否"]:
|
||||||
enable = False
|
enable = False
|
||||||
else:
|
else:
|
||||||
error_msg = f"无效的enable参数: {enable},应该是True或False"
|
error_msg = f"无效的enable参数: {enable},应该是True或False"
|
||||||
@@ -54,20 +52,12 @@ class GroupWholeBanAction(PluginAction):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
# 发送群聊全体禁言命令,按照新格式
|
# 发送群聊全体禁言命令,按照新格式
|
||||||
await self.send_message(
|
await self.send_message(type="command", data={"name": "GROUP_WHOLE_BAN", "args": {"enable": enable}})
|
||||||
type="command",
|
|
||||||
data={
|
|
||||||
"name": "GROUP_WHOLE_BAN",
|
|
||||||
"args": {
|
|
||||||
"enable": enable
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
logger.info(f"{self.log_prefix} 成功{action_text}全体禁言")
|
logger.info(f"{self.log_prefix} 成功{action_text}全体禁言")
|
||||||
return True, f"成功{action_text}全体禁言"
|
return True, f"成功{action_text}全体禁言"
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"{self.log_prefix} 执行全体禁言动作时出错: {e}")
|
logger.error(f"{self.log_prefix} 执行全体禁言动作时出错: {e}")
|
||||||
await self.send_message_by_expressor(f"执行全体禁言动作时出错: {e}")
|
await self.send_message_by_expressor(f"执行全体禁言动作时出错: {e}")
|
||||||
return False, f"执行全体禁言动作时出错: {e}"
|
return False, f"执行全体禁言动作时出错: {e}"
|
||||||
|
|||||||
@@ -10,9 +10,7 @@ class MuteAction(PluginAction):
|
|||||||
"""群聊禁言动作处理类"""
|
"""群聊禁言动作处理类"""
|
||||||
|
|
||||||
action_name = "mute_action"
|
action_name = "mute_action"
|
||||||
action_description = (
|
action_description = "如果某人违反了公序良俗,或者别人戳你太多,或者某人刷屏,一定要禁言某人,如果你很生气,可以禁言某人,可以自选禁言时长,视严重程度而定。"
|
||||||
"如果某人违反了公序良俗,或者别人戳你太多,或者某人刷屏,一定要禁言某人,如果你很生气,可以禁言某人,可以自选禁言时长,视严重程度而定。"
|
|
||||||
)
|
|
||||||
action_parameters = {
|
action_parameters = {
|
||||||
"target": "禁言对象,输入你要禁言的对象的名字,必填",
|
"target": "禁言对象,输入你要禁言的对象的名字,必填",
|
||||||
"duration": "禁言时长,输入你要禁言的时长,单位为秒,必填,必须为数字",
|
"duration": "禁言时长,输入你要禁言的时长,单位为秒,必填,必须为数字",
|
||||||
@@ -38,7 +36,7 @@ class MuteAction(PluginAction):
|
|||||||
target = self.action_data.get("target")
|
target = self.action_data.get("target")
|
||||||
duration = self.action_data.get("duration")
|
duration = self.action_data.get("duration")
|
||||||
reason = self.action_data.get("reason", "违反群规")
|
reason = self.action_data.get("reason", "违反群规")
|
||||||
|
|
||||||
if not target or not duration:
|
if not target or not duration:
|
||||||
error_msg = "禁言参数不完整,需要target和duration"
|
error_msg = "禁言参数不完整,需要target和duration"
|
||||||
logger.error(f"{self.log_prefix} {error_msg}")
|
logger.error(f"{self.log_prefix} {error_msg}")
|
||||||
@@ -46,7 +44,7 @@ class MuteAction(PluginAction):
|
|||||||
|
|
||||||
# 获取用户ID
|
# 获取用户ID
|
||||||
platform, user_id = await self.get_user_id_by_person_name(target)
|
platform, user_id = await self.get_user_id_by_person_name(target)
|
||||||
|
|
||||||
if not user_id:
|
if not user_id:
|
||||||
error_msg = f"未找到用户 {target} 的ID"
|
error_msg = f"未找到用户 {target} 的ID"
|
||||||
logger.error(f"{self.log_prefix} {error_msg}")
|
logger.error(f"{self.log_prefix} {error_msg}")
|
||||||
@@ -58,19 +56,12 @@ class MuteAction(PluginAction):
|
|||||||
try:
|
try:
|
||||||
# 确保duration是字符串类型
|
# 确保duration是字符串类型
|
||||||
duration_str = str(duration)
|
duration_str = str(duration)
|
||||||
|
|
||||||
# 发送群聊禁言命令,按照新格式
|
# 发送群聊禁言命令,按照新格式
|
||||||
await self.send_message(
|
await self.send_message(
|
||||||
type="command",
|
type="command", data={"name": "GROUP_BAN", "args": {"qq_id": str(user_id), "duration": duration_str}}
|
||||||
data={
|
|
||||||
"name": "GROUP_BAN",
|
|
||||||
"args": {
|
|
||||||
"qq_id": str(user_id),
|
|
||||||
"duration": duration_str
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
logger.info(f"{self.log_prefix} 成功禁言用户 {target}({user_id}),时长 {duration} 秒")
|
logger.info(f"{self.log_prefix} 成功禁言用户 {target}({user_id}),时长 {duration} 秒")
|
||||||
return True, f"成功禁言 {target},时长 {duration} 秒"
|
return True, f"成功禁言 {target},时长 {duration} 秒"
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ from src.common.logger_manager import get_logger
|
|||||||
from src.tools.tool_can_use import get_all_tool_definitions, get_tool_instance
|
from src.tools.tool_can_use import get_all_tool_definitions, get_tool_instance
|
||||||
|
|
||||||
logger = get_logger("tool_use")
|
logger = get_logger("tool_use")
|
||||||
|
|
||||||
|
|
||||||
class ToolUser:
|
class ToolUser:
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _define_tools():
|
def _define_tools():
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ talk_frequency_down_groups = [] #降低回复频率的群号码
|
|||||||
|
|
||||||
[focus_chat] #专注聊天
|
[focus_chat] #专注聊天
|
||||||
auto_focus_threshold = 1 # 自动切换到专注聊天的阈值,越低越容易进入专注聊天
|
auto_focus_threshold = 1 # 自动切换到专注聊天的阈值,越低越容易进入专注聊天
|
||||||
|
exit_focus_threshold = 1 # 自动退出专注聊天的阈值,越低越容易退出专注聊天
|
||||||
consecutive_no_reply_threshold = 3 # 连续不回复的阈值,越低越容易结束专注聊天
|
consecutive_no_reply_threshold = 3 # 连续不回复的阈值,越低越容易结束专注聊天
|
||||||
|
|
||||||
think_interval = 3 # 思考间隔 单位秒,可以有效减少消耗
|
think_interval = 3 # 思考间隔 单位秒,可以有效减少消耗
|
||||||
|
|||||||
Reference in New Issue
Block a user