feat: 增加连续超时计数和用户最后回复时间,优化超时决策上下文信息
This commit is contained in:
@@ -385,7 +385,13 @@ class ProactiveThinker:
|
||||
)
|
||||
return
|
||||
|
||||
logger.info(f"[ProactiveThinker] 等待超时: user={session.user_id}")
|
||||
# 增加连续超时计数
|
||||
session.consecutive_timeout_count += 1
|
||||
|
||||
logger.info(
|
||||
f"[ProactiveThinker] 等待超时: user={session.user_id}, "
|
||||
f"consecutive_timeout={session.consecutive_timeout_count}"
|
||||
)
|
||||
|
||||
try:
|
||||
# 获取用户名
|
||||
@@ -403,6 +409,18 @@ class ProactiveThinker:
|
||||
action_modifier = ActionModifier(action_manager, session.stream_id)
|
||||
await action_modifier.modify_actions(chatter_name="KokoroFlowChatter")
|
||||
|
||||
# 计算用户最后回复距今的时间
|
||||
time_since_user_reply = None
|
||||
if session.last_user_message_at:
|
||||
time_since_user_reply = time.time() - session.last_user_message_at
|
||||
|
||||
# 构建超时上下文信息
|
||||
extra_context = {
|
||||
"consecutive_timeout_count": session.consecutive_timeout_count,
|
||||
"time_since_user_reply": time_since_user_reply,
|
||||
"time_since_user_reply_str": self._format_duration(time_since_user_reply) if time_since_user_reply else "未知",
|
||||
}
|
||||
|
||||
# 调用 Planner 生成超时决策
|
||||
plan_response = await generate_plan(
|
||||
session=session,
|
||||
@@ -410,6 +428,7 @@ class ProactiveThinker:
|
||||
situation_type="timeout",
|
||||
chat_stream=chat_stream,
|
||||
available_actions=action_manager.get_using_actions(),
|
||||
extra_context=extra_context,
|
||||
)
|
||||
|
||||
# 为 kfc_reply 动作注入必要的上下文信息
|
||||
@@ -419,6 +438,7 @@ class ProactiveThinker:
|
||||
action.params["user_name"] = user_name
|
||||
action.params["thought"] = plan_response.thought
|
||||
action.params["situation_type"] = "timeout"
|
||||
action.params["extra_context"] = extra_context
|
||||
|
||||
# 执行动作(回复生成在 Action.execute() 中完成)
|
||||
for action in plan_response.actions:
|
||||
@@ -457,7 +477,8 @@ class ProactiveThinker:
|
||||
logger.info(
|
||||
f"[ProactiveThinker] 超时决策完成: user={session.user_id}, "
|
||||
f"actions={[a.type for a in plan_response.actions]}, "
|
||||
f"continue_wait={plan_response.max_wait_seconds > 0}"
|
||||
f"continue_wait={plan_response.max_wait_seconds > 0}, "
|
||||
f"consecutive_timeout={session.consecutive_timeout_count}"
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
@@ -681,6 +702,23 @@ class ProactiveThinker:
|
||||
# 回退到 user_id
|
||||
return user_id
|
||||
|
||||
def _format_duration(self, seconds: float | None) -> str:
|
||||
"""格式化时间间隔为人类可读的字符串"""
|
||||
if seconds is None or seconds < 0:
|
||||
return "未知"
|
||||
|
||||
if seconds < 60:
|
||||
return f"{int(seconds)} 秒"
|
||||
elif seconds < 3600:
|
||||
minutes = seconds / 60
|
||||
return f"{minutes:.0f} 分钟"
|
||||
elif seconds < 86400:
|
||||
hours = seconds / 3600
|
||||
return f"{hours:.1f} 小时"
|
||||
else:
|
||||
days = seconds / 86400
|
||||
return f"{days:.1f} 天"
|
||||
|
||||
def get_stats(self) -> dict:
|
||||
"""获取统计信息"""
|
||||
return {
|
||||
|
||||
@@ -531,6 +531,24 @@ class PromptBuilder:
|
||||
elapsed = session.waiting_config.get_elapsed_seconds()
|
||||
max_wait = session.waiting_config.max_wait_seconds
|
||||
expected = session.waiting_config.expected_reaction
|
||||
|
||||
# 构建连续超时上下文
|
||||
timeout_context_parts = []
|
||||
|
||||
# 添加连续超时次数信息
|
||||
consecutive_count = extra_context.get("consecutive_timeout_count", 0)
|
||||
if consecutive_count > 1:
|
||||
timeout_context_parts.append(f"⚠️ 这已经是你连续第 {consecutive_count} 次等到超时了。")
|
||||
|
||||
# 添加距离用户上次回复的时间
|
||||
time_since_user_reply_str = extra_context.get("time_since_user_reply_str")
|
||||
if time_since_user_reply_str:
|
||||
timeout_context_parts.append(f"距离 {user_name} 上一次回复你已经过去了 {time_since_user_reply_str}。")
|
||||
|
||||
timeout_context = "\n".join(timeout_context_parts)
|
||||
if timeout_context:
|
||||
timeout_context = "\n" + timeout_context + "\n"
|
||||
|
||||
return await global_prompt_manager.format_prompt(
|
||||
PROMPT_NAMES["situation_timeout"],
|
||||
current_time=current_time,
|
||||
@@ -538,6 +556,7 @@ class PromptBuilder:
|
||||
elapsed_minutes=elapsed / 60,
|
||||
max_wait_minutes=max_wait / 60,
|
||||
expected_reaction=expected or "对方能回复点什么",
|
||||
timeout_context=timeout_context,
|
||||
)
|
||||
|
||||
elif situation_type == "proactive":
|
||||
|
||||
@@ -123,12 +123,15 @@ kfc_SITUATION_TIMEOUT = Prompt(
|
||||
你之前发了消息后一直在等 {user_name} 的回复。
|
||||
你原本打算最多等 {max_wait_minutes:.1f} 分钟,现在已经等了 {elapsed_minutes:.1f} 分钟了,对方还是没回。
|
||||
你当时期待的反应是:"{expected_reaction}"
|
||||
|
||||
{timeout_context}
|
||||
你需要决定:
|
||||
1. 继续等待(设置新的 max_wait_seconds)
|
||||
2. 主动说点什么打破沉默
|
||||
3. 做点别的事情(执行其他动作)
|
||||
4. 算了不等了(max_wait_seconds = 0)""",
|
||||
4. 算了不等了(max_wait_seconds = 0)
|
||||
|
||||
【注意】如果已经连续多次超时,对方可能暂时不方便回复。频繁主动发消息可能会打扰到对方。
|
||||
考虑是否应该暂时放下期待,让对方有空间。""",
|
||||
)
|
||||
|
||||
kfc_SITUATION_PROACTIVE = Prompt(
|
||||
|
||||
@@ -66,6 +66,12 @@ class KokoroSession:
|
||||
|
||||
# 上次主动思考时间
|
||||
self.last_proactive_at: Optional[float] = None
|
||||
|
||||
# 连续超时计数(用于避免过度打扰用户)
|
||||
self.consecutive_timeout_count: int = 0
|
||||
|
||||
# 用户最后发消息的时间(用于计算距离用户上次回复的时间)
|
||||
self.last_user_message_at: Optional[float] = None
|
||||
|
||||
@property
|
||||
def status(self) -> SessionStatus:
|
||||
@@ -95,14 +101,20 @@ class KokoroSession:
|
||||
timestamp: Optional[float] = None,
|
||||
) -> MentalLogEntry:
|
||||
"""添加用户消息事件"""
|
||||
msg_time = timestamp or time.time()
|
||||
|
||||
entry = MentalLogEntry(
|
||||
event_type=EventType.USER_MESSAGE,
|
||||
timestamp=timestamp or time.time(),
|
||||
timestamp=msg_time,
|
||||
content=content,
|
||||
user_name=user_name,
|
||||
user_id=user_id,
|
||||
)
|
||||
|
||||
# 收到用户消息,重置连续超时计数
|
||||
self.consecutive_timeout_count = 0
|
||||
self.last_user_message_at = msg_time
|
||||
|
||||
# 如果之前在等待,记录收到回复的情况
|
||||
if self.status == SessionStatus.WAITING and self.waiting_config.is_active():
|
||||
elapsed = self.waiting_config.get_elapsed_seconds()
|
||||
@@ -213,6 +225,8 @@ class KokoroSession:
|
||||
"last_activity_at": self.last_activity_at,
|
||||
"total_interactions": self.total_interactions,
|
||||
"last_proactive_at": self.last_proactive_at,
|
||||
"consecutive_timeout_count": self.consecutive_timeout_count,
|
||||
"last_user_message_at": self.last_user_message_at,
|
||||
}
|
||||
|
||||
@classmethod
|
||||
@@ -244,6 +258,10 @@ class KokoroSession:
|
||||
session.total_interactions = data.get("total_interactions", 0)
|
||||
session.last_proactive_at = data.get("last_proactive_at")
|
||||
|
||||
# 连续超时相关
|
||||
session.consecutive_timeout_count = data.get("consecutive_timeout_count", 0)
|
||||
session.last_user_message_at = data.get("last_user_message_at")
|
||||
|
||||
return session
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user