mirror of https://github.com/Mai-with-u/MaiBot.git
feat:wait可被打断,不推荐修改私聊planner
parent
92a7836103
commit
a8c25cdc15
|
|
@ -87,6 +87,7 @@ class BrainChatting:
|
||||||
# 循环控制内部状态
|
# 循环控制内部状态
|
||||||
self.running: bool = False
|
self.running: bool = False
|
||||||
self._loop_task: Optional[asyncio.Task] = None # 主循环任务
|
self._loop_task: Optional[asyncio.Task] = None # 主循环任务
|
||||||
|
self._new_message_event = asyncio.Event() # 新消息事件,用于打断 wait
|
||||||
|
|
||||||
# 添加循环信息管理相关的属性
|
# 添加循环信息管理相关的属性
|
||||||
self.history_loop: List[CycleDetail] = []
|
self.history_loop: List[CycleDetail] = []
|
||||||
|
|
@ -173,9 +174,10 @@ class BrainChatting:
|
||||||
filter_intercept_message_level=1,
|
filter_intercept_message_level=1,
|
||||||
)
|
)
|
||||||
|
|
||||||
# 如果有新消息,更新 last_read_time
|
# 如果有新消息,更新 last_read_time 并触发事件以打断正在进行的 wait
|
||||||
if len(recent_messages_list) >= 1:
|
if len(recent_messages_list) >= 1:
|
||||||
self.last_read_time = time.time()
|
self.last_read_time = time.time()
|
||||||
|
self._new_message_event.set() # 触发新消息事件,打断 wait
|
||||||
|
|
||||||
# 总是执行一次思考迭代(不管有没有新消息)
|
# 总是执行一次思考迭代(不管有没有新消息)
|
||||||
# wait 动作会在其内部等待,不需要在这里处理
|
# wait 动作会在其内部等待,不需要在这里处理
|
||||||
|
|
@ -434,6 +436,9 @@ class BrainChatting:
|
||||||
last_check_time = self.last_read_time
|
last_check_time = self.last_read_time
|
||||||
check_interval = 1.0 # 每秒检查一次
|
check_interval = 1.0 # 每秒检查一次
|
||||||
|
|
||||||
|
# 清除事件状态,准备等待新消息
|
||||||
|
self._new_message_event.clear()
|
||||||
|
|
||||||
while self.running:
|
while self.running:
|
||||||
# 检查是否有新消息
|
# 检查是否有新消息
|
||||||
recent_messages_list = message_api.get_messages_by_time_in_chat(
|
recent_messages_list = message_api.get_messages_by_time_in_chat(
|
||||||
|
|
@ -453,8 +458,15 @@ class BrainChatting:
|
||||||
logger.info(f"{self.log_prefix} 检测到新消息,恢复循环")
|
logger.info(f"{self.log_prefix} 检测到新消息,恢复循环")
|
||||||
return
|
return
|
||||||
|
|
||||||
# 等待一段时间后再次检查
|
# 等待新消息事件或超时后再次检查
|
||||||
await asyncio.sleep(check_interval)
|
try:
|
||||||
|
await asyncio.wait_for(self._new_message_event.wait(), timeout=check_interval)
|
||||||
|
# 事件被触发,说明有新消息
|
||||||
|
logger.info(f"{self.log_prefix} 检测到新消息事件,恢复循环")
|
||||||
|
return
|
||||||
|
except asyncio.TimeoutError:
|
||||||
|
# 超时后继续检查
|
||||||
|
continue
|
||||||
|
|
||||||
async def _handle_action(
|
async def _handle_action(
|
||||||
self,
|
self,
|
||||||
|
|
@ -674,7 +686,10 @@ class BrainChatting:
|
||||||
logger.warning(f"{self.log_prefix} wait_seconds 参数格式错误,使用默认值 5 秒")
|
logger.warning(f"{self.log_prefix} wait_seconds 参数格式错误,使用默认值 5 秒")
|
||||||
wait_seconds = 5
|
wait_seconds = 5
|
||||||
|
|
||||||
logger.info(f"{self.log_prefix} 执行 wait 动作,等待 {wait_seconds} 秒")
|
logger.info(f"{self.log_prefix} 执行 wait 动作,等待 {wait_seconds} 秒(可被新消息打断)")
|
||||||
|
|
||||||
|
# 清除事件状态,准备等待新消息
|
||||||
|
self._new_message_event.clear()
|
||||||
|
|
||||||
# 记录动作信息
|
# 记录动作信息
|
||||||
await database_api.store_action_info(
|
await database_api.store_action_info(
|
||||||
|
|
@ -687,8 +702,17 @@ class BrainChatting:
|
||||||
action_name="wait",
|
action_name="wait",
|
||||||
)
|
)
|
||||||
|
|
||||||
# 等待指定时间
|
# 等待指定时间,但可被新消息打断
|
||||||
await asyncio.sleep(wait_seconds)
|
try:
|
||||||
|
await asyncio.wait_for(
|
||||||
|
self._new_message_event.wait(),
|
||||||
|
timeout=wait_seconds
|
||||||
|
)
|
||||||
|
# 如果事件被触发,说明有新消息到达
|
||||||
|
logger.info(f"{self.log_prefix} wait 动作被新消息打断,提前结束等待")
|
||||||
|
except asyncio.TimeoutError:
|
||||||
|
# 超时正常完成
|
||||||
|
pass
|
||||||
|
|
||||||
logger.info(f"{self.log_prefix} wait 动作完成,继续下一次思考")
|
logger.info(f"{self.log_prefix} wait 动作完成,继续下一次思考")
|
||||||
|
|
||||||
|
|
@ -707,7 +731,10 @@ class BrainChatting:
|
||||||
# 使用默认等待时间
|
# 使用默认等待时间
|
||||||
wait_seconds = 3
|
wait_seconds = 3
|
||||||
|
|
||||||
logger.info(f"{self.log_prefix} 执行 listening(转换为 wait)动作,等待 {wait_seconds} 秒")
|
logger.info(f"{self.log_prefix} 执行 listening(转换为 wait)动作,等待 {wait_seconds} 秒(可被新消息打断)")
|
||||||
|
|
||||||
|
# 清除事件状态,准备等待新消息
|
||||||
|
self._new_message_event.clear()
|
||||||
|
|
||||||
# 记录动作信息
|
# 记录动作信息
|
||||||
await database_api.store_action_info(
|
await database_api.store_action_info(
|
||||||
|
|
@ -720,8 +747,17 @@ class BrainChatting:
|
||||||
action_name="listening",
|
action_name="listening",
|
||||||
)
|
)
|
||||||
|
|
||||||
# 等待指定时间
|
# 等待指定时间,但可被新消息打断
|
||||||
await asyncio.sleep(wait_seconds)
|
try:
|
||||||
|
await asyncio.wait_for(
|
||||||
|
self._new_message_event.wait(),
|
||||||
|
timeout=wait_seconds
|
||||||
|
)
|
||||||
|
# 如果事件被触发,说明有新消息到达
|
||||||
|
logger.info(f"{self.log_prefix} listening 动作被新消息打断,提前结束等待")
|
||||||
|
except asyncio.TimeoutError:
|
||||||
|
# 超时正常完成
|
||||||
|
pass
|
||||||
|
|
||||||
logger.info(f"{self.log_prefix} listening 动作完成,继续下一次思考")
|
logger.info(f"{self.log_prefix} listening 动作完成,继续下一次思考")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -402,7 +402,7 @@ class BrainPlanner:
|
||||||
moderation_prompt=moderation_prompt_block,
|
moderation_prompt=moderation_prompt_block,
|
||||||
name_block=name_block,
|
name_block=name_block,
|
||||||
interest=interest,
|
interest=interest,
|
||||||
plan_style=global_config.personality.private_plan_style,
|
plan_style=global_config.experimental.private_plan_style,
|
||||||
)
|
)
|
||||||
|
|
||||||
return prompt, message_id_list
|
return prompt, message_id_list
|
||||||
|
|
|
||||||
|
|
@ -57,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.12.1"
|
MMC_VERSION = "0.12.2"
|
||||||
|
|
||||||
|
|
||||||
def get_key_comment(toml_table, key):
|
def get_key_comment(toml_table, key):
|
||||||
|
|
|
||||||
|
|
@ -57,9 +57,6 @@ class PersonalityConfig(ConfigBase):
|
||||||
visual_style: str = ""
|
visual_style: str = ""
|
||||||
"""图片提示词"""
|
"""图片提示词"""
|
||||||
|
|
||||||
private_plan_style: str = ""
|
|
||||||
"""私聊说话规则,行为风格"""
|
|
||||||
|
|
||||||
states: list[str] = field(default_factory=lambda: [])
|
states: list[str] = field(default_factory=lambda: [])
|
||||||
"""状态列表,用于随机替换personality"""
|
"""状态列表,用于随机替换personality"""
|
||||||
|
|
||||||
|
|
@ -713,8 +710,8 @@ class DebugConfig(ConfigBase):
|
||||||
class ExperimentalConfig(ConfigBase):
|
class ExperimentalConfig(ConfigBase):
|
||||||
"""实验功能配置类"""
|
"""实验功能配置类"""
|
||||||
|
|
||||||
enable_friend_chat: bool = False
|
private_plan_style: str = ""
|
||||||
"""是否启用好友聊天"""
|
"""私聊说话规则,行为风格(实验性功能)"""
|
||||||
|
|
||||||
chat_prompts: list[str] = field(default_factory=lambda: [])
|
chat_prompts: list[str] = field(default_factory=lambda: [])
|
||||||
"""
|
"""
|
||||||
|
|
@ -904,6 +901,13 @@ class DreamConfig(ConfigBase):
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
dream_visible: bool = False
|
||||||
|
"""
|
||||||
|
做梦结果是否存储到上下文
|
||||||
|
- True: 将梦境发送给配置的用户后,也会存储到聊天上下文中,在后续对话中可见
|
||||||
|
- False: 仅发送梦境但不存储,不在后续对话上下文中出现
|
||||||
|
"""
|
||||||
|
|
||||||
def __post_init__(self):
|
def __post_init__(self):
|
||||||
"""验证配置值"""
|
"""验证配置值"""
|
||||||
if self.interval_minutes < 1:
|
if self.interval_minutes < 1:
|
||||||
|
|
|
||||||
|
|
@ -215,11 +215,12 @@ async def generate_dream_summary(
|
||||||
f"platform={platform!r}, user_id={user_id!r}"
|
f"platform={platform!r}, user_id={user_id!r}"
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
|
dream_visible = global_config.dream.dream_visible
|
||||||
ok = await send_api.text_to_stream(
|
ok = await send_api.text_to_stream(
|
||||||
dream_content,
|
dream_content,
|
||||||
stream_id=stream_id,
|
stream_id=stream_id,
|
||||||
typing=False,
|
typing=False,
|
||||||
storage_message=True,
|
storage_message=dream_visible,
|
||||||
)
|
)
|
||||||
if ok:
|
if ok:
|
||||||
logger.info(
|
logger.info(
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
[inner]
|
[inner]
|
||||||
version = "7.3.3"
|
version = "7.3.5"
|
||||||
|
|
||||||
#----以下是给开发人员阅读的,如果你只是部署了麦麦,不需要阅读----
|
#----以下是给开发人员阅读的,如果你只是部署了麦麦,不需要阅读----
|
||||||
# 如果你想要修改配置文件,请递增version的值
|
# 如果你想要修改配置文件,请递增version的值
|
||||||
|
|
@ -40,20 +40,11 @@ multiple_reply_style = [
|
||||||
multiple_probability = 0.3
|
multiple_probability = 0.3
|
||||||
|
|
||||||
# 麦麦的说话规则和行为规则:
|
# 麦麦的说话规则和行为规则:
|
||||||
plan_style = """
|
plan_style = """1.思考**所有**的可用的action中的**每个动作**是否符合当下条件,如果动作使用条件符合聊天内容就使用
|
||||||
1.思考**所有**的可用的action中的**每个动作**是否符合当下条件,如果动作使用条件符合聊天内容就使用
|
2.如果相同的action已经被执行,请不要重复执行该action
|
||||||
2.如果相同的内容已经被执行,请不要重复执行
|
3.如果有人对你感到厌烦,请减少回复
|
||||||
3.你对技术相关话题,游戏和动漫相关话题感兴趣,也对日常话题感兴趣,不喜欢太过沉重严肃的话题
|
4.如果有人在追问你,或者话题没有说完,请你继续回复
|
||||||
4.请控制你的发言频率,不要太过频繁的发言
|
5.请分析哪些对话是和你说的,哪些是其他人之间的互动,不要误认为其他人之间的互动是和你说的"""
|
||||||
5.如果有人对你感到厌烦,请减少回复
|
|
||||||
6.如果有人在追问你,或者话题没有说完,请你继续回复"""
|
|
||||||
|
|
||||||
|
|
||||||
# 麦麦私聊的说话规则,行为风格:
|
|
||||||
private_plan_style = """
|
|
||||||
1.思考**所有**的可用的action中的**每个动作**是否符合当下条件,如果动作使用条件符合聊天内容就使用
|
|
||||||
2.如果相同的内容已经被执行,请不要重复执行
|
|
||||||
3.某句话如果已经被回复过,不要重复回复"""
|
|
||||||
|
|
||||||
# 多重人格,根据概率随机选择人格
|
# 多重人格,根据概率随机选择人格
|
||||||
states = [
|
states = [
|
||||||
|
|
@ -153,6 +144,7 @@ first_delay_seconds = 1800 # 程序启动后首次做梦前的延迟时间(秒
|
||||||
# 为空字符串时不推送。
|
# 为空字符串时不推送。
|
||||||
dream_send = ""
|
dream_send = ""
|
||||||
|
|
||||||
|
dream_visible = false # 做梦结果是否存储到上下文,True: 将梦境发送给配置的用户后,也会存储到聊天上下文中,在后续对话中可见;False: 仅发送梦境但不存储,不在后续对话上下文中出现
|
||||||
# 做梦时间段配置,格式:["HH:MM-HH:MM", ...]
|
# 做梦时间段配置,格式:["HH:MM-HH:MM", ...]
|
||||||
# 如果列表为空,则表示全天允许做梦。
|
# 如果列表为空,则表示全天允许做梦。
|
||||||
# 如果配置了时间段,则只有在这些时间段内才会实际执行做梦流程。
|
# 如果配置了时间段,则只有在这些时间段内才会实际执行做梦流程。
|
||||||
|
|
@ -298,6 +290,12 @@ trust_xff = false # 是否启用X-Forwarded-For代理解析(默认false)
|
||||||
secure_cookie = false # 是否启用安全Cookie(仅通过HTTPS传输,默认false)
|
secure_cookie = false # 是否启用安全Cookie(仅通过HTTPS传输,默认false)
|
||||||
|
|
||||||
[experimental] #实验性功能
|
[experimental] #实验性功能
|
||||||
|
# 麦麦私聊的说话规则,行为风格(实验性功能)
|
||||||
|
private_plan_style = """
|
||||||
|
1.思考**所有**的可用的action中的**每个动作**是否符合当下条件,如果动作使用条件符合聊天内容就使用
|
||||||
|
2.如果相同的内容已经被执行,请不要重复执行
|
||||||
|
3.某句话如果已经被回复过,不要重复回复"""
|
||||||
|
|
||||||
# 为指定聊天添加额外的prompt配置
|
# 为指定聊天添加额外的prompt配置
|
||||||
# 格式: ["platform:id:type:prompt内容", ...]
|
# 格式: ["platform:id:type:prompt内容", ...]
|
||||||
# 示例:
|
# 示例:
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue