brain_chat无新消息限定动作:reply/wait,complete_talk

pull/1502/head
xiaoxi68 2026-02-07 19:48:11 +08:00
parent ad4bfb739f
commit c92581afe7
2 changed files with 52 additions and 14 deletions

View File

@ -104,7 +104,7 @@ class BrainChatting:
# side-effect 动作幂等缓存,避免同一触发消息在短时间内重复执行。
self._recent_side_effect_actions: Dict[str, float] = {}
self._side_effect_dedupe_window_sec = 100.0
self._side_effect_dedupe_window_sec = 10.0
async def start(self):
"""检查是否需要启动主循环,如果未激活则启动。"""
@ -213,13 +213,11 @@ class BrainChatting:
filter_intercept_message_level=1,
)
# 没有新增用户消息时,直接等待下一轮,避免对旧上下文反复规划。
if not recent_messages_list:
await asyncio.sleep(0.2)
return True
self.last_read_time = time.time()
self._new_message_event.set() # 触发新消息事件,打断正在进行的 wait
# 仅在有新消息时更新读取时间并触发事件。
# 无新消息时仍允许继续思考,具体动作由 Planner 限制为 reply/wait。
if recent_messages_list:
self.last_read_time = time.time()
self._new_message_event.set() # 触发新消息事件,打断正在进行的 wait
should_continue = await self._observe(recent_messages_list=recent_messages_list)

View File

@ -330,14 +330,16 @@ class BrainPlanner:
for msg in message_list_before_now
)
if not has_new_user_message:
non_side_effect_actions = {"reply", "wait", "wait_time", "listening", "complete_talk", "no_reply"}
side_effect_actions = [a.action_type for a in actions if a.action_type not in non_side_effect_actions]
if side_effect_actions:
actions, dropped_actions = self._restrict_actions_without_new_user_message(
actions=actions,
available_actions=available_actions,
message_id_list=message_id_list,
)
if dropped_actions:
logger.info(
f"{self.log_prefix}检测到无新用户消息,跳过副作用动作: {' '.join(side_effect_actions)}"
f"{self.log_prefix}检测到无新用户消息,仅保留 reply/wait/complete_talk移除动作: {' '.join(dropped_actions)}"
)
actions = self._create_complete_talk("没有新的用户消息,跳过副作用动作", available_actions)
reasoning = f"{reasoning};检测到无新用户消息,已跳过副作用动作"
reasoning = f"{reasoning};检测到无新用户消息,仅保留 reply/wait/complete_talk"
# 记录和展示计划日志
logger.info(
@ -611,6 +613,44 @@ class BrainPlanner:
)
]
def _restrict_actions_without_new_user_message(
self,
actions: List[ActionPlannerInfo],
available_actions: Dict[str, ActionInfo],
message_id_list: List[Tuple[str, "DatabaseMessages"]],
) -> Tuple[List[ActionPlannerInfo], List[str]]:
"""无新用户消息时,仅保留 reply/wait/complete_talk。"""
allowed_actions: List[ActionPlannerInfo] = []
dropped_actions: List[str] = []
for action in actions:
if action.action_type in {"reply", "complete_talk"}:
allowed_actions.append(action)
continue
if action.action_type in {"wait", "listening", "wait_time"}:
action.action_type = "wait"
action.action_data = action.action_data or {}
action.action_data.setdefault("wait_seconds", 5)
allowed_actions.append(action)
continue
dropped_actions.append(action.action_type)
if allowed_actions:
return allowed_actions, dropped_actions
target_message = message_id_list[-1][1] if message_id_list else None
fallback_wait = ActionPlannerInfo(
action_type="wait",
reasoning="没有新的用户消息,进入等待",
action_data={"wait_seconds": 5},
action_message=target_message,
available_actions=available_actions,
)
return [fallback_wait], dropped_actions
def add_plan_log(self, reasoning: str, actions: List[ActionPlannerInfo]):
"""添加计划日志"""
self.plan_log.append((reasoning, time.time(), actions))