fix: 修复名字识别错
This commit is contained in:
@@ -37,24 +37,57 @@ class InterestMonitorApp:
|
|||||||
# 使用 deque 来存储有限的历史数据点
|
# 使用 deque 来存储有限的历史数据点
|
||||||
# key: stream_id, value: deque([(timestamp, interest_level), ...])
|
# key: stream_id, value: deque([(timestamp, interest_level), ...])
|
||||||
self.stream_history = {}
|
self.stream_history = {}
|
||||||
# key: stream_id, value: deque([(timestamp, reply_probability), ...]) # <--- 新增:存储概率历史
|
# key: stream_id, value: deque([(timestamp, reply_probability), ...])
|
||||||
self.probability_history = {}
|
self.probability_history = {}
|
||||||
self.stream_colors = {} # 为每个 stream 分配颜色
|
self.stream_colors = {} # 为每个 stream 分配颜色
|
||||||
self.stream_display_names = {} # *** New: Store display names (group_name) ***
|
self.stream_display_names = {} # 存储显示名称 (group_name)
|
||||||
self.selected_stream_id = tk.StringVar() # 用于 Combobox 绑定
|
self.selected_stream_id = tk.StringVar() # 用于 Combobox 绑定
|
||||||
|
|
||||||
|
# --- 新增:存储其他参数 ---
|
||||||
|
# 顶层信息
|
||||||
|
self.latest_main_mind = tk.StringVar(value="N/A")
|
||||||
|
self.latest_mai_state = tk.StringVar(value="N/A")
|
||||||
|
self.latest_subflow_count = tk.IntVar(value=0)
|
||||||
|
# 子流最新状态 (key: stream_id)
|
||||||
|
self.stream_sub_minds = {}
|
||||||
|
self.stream_chat_states = {}
|
||||||
|
self.stream_threshold_status = {}
|
||||||
|
self.stream_last_active = {}
|
||||||
|
self.stream_last_interaction = {}
|
||||||
|
# 用于显示单个流详情的 StringVar
|
||||||
|
self.single_stream_sub_mind = tk.StringVar(value="想法: N/A")
|
||||||
|
self.single_stream_chat_state = tk.StringVar(value="状态: N/A")
|
||||||
|
self.single_stream_threshold = tk.StringVar(value="阈值: N/A")
|
||||||
|
self.single_stream_last_active = tk.StringVar(value="活跃: N/A")
|
||||||
|
self.single_stream_last_interaction = tk.StringVar(value="交互: N/A")
|
||||||
|
|
||||||
|
|
||||||
# --- UI 元素 ---
|
# --- UI 元素 ---
|
||||||
|
|
||||||
|
# --- 新增:顶部全局信息框架 ---
|
||||||
|
self.global_info_frame = ttk.Frame(root, padding="5 0 5 5") # 顶部内边距调整
|
||||||
|
self.global_info_frame.pack(side=tk.TOP, fill=tk.X, pady=(5, 0)) # 底部外边距为0
|
||||||
|
|
||||||
|
ttk.Label(self.global_info_frame, text="全局状态:").pack(side=tk.LEFT, padx=(0, 10))
|
||||||
|
ttk.Label(self.global_info_frame, textvariable=self.latest_mai_state).pack(side=tk.LEFT, padx=5)
|
||||||
|
ttk.Label(self.global_info_frame, text="想法:").pack(side=tk.LEFT, padx=(10, 0))
|
||||||
|
ttk.Label(self.global_info_frame, textvariable=self.latest_main_mind).pack(side=tk.LEFT, padx=5)
|
||||||
|
ttk.Label(self.global_info_frame, text="子流数:").pack(side=tk.LEFT, padx=(10, 0))
|
||||||
|
ttk.Label(self.global_info_frame, textvariable=self.latest_subflow_count).pack(side=tk.LEFT, padx=5)
|
||||||
|
|
||||||
|
|
||||||
# 创建 Notebook (选项卡控件)
|
# 创建 Notebook (选项卡控件)
|
||||||
self.notebook = ttk.Notebook(root)
|
self.notebook = ttk.Notebook(root)
|
||||||
self.notebook.pack(pady=10, padx=10, fill=tk.BOTH, expand=1)
|
# 修改:fill 和 expand,让 notebook 填充剩余空间
|
||||||
|
self.notebook.pack(pady=(5, 0), padx=10, fill=tk.BOTH, expand=1) #顶部外边距改小
|
||||||
|
|
||||||
# --- 第一个选项卡:所有流 ---
|
# --- 第一个选项卡:所有流 ---
|
||||||
self.frame_all = ttk.Frame(self.notebook, padding="5 5 5 5")
|
self.frame_all = ttk.Frame(self.notebook, padding="5 5 5 5")
|
||||||
self.notebook.add(self.frame_all, text="所有聊天流")
|
self.notebook.add(self.frame_all, text="所有聊天流")
|
||||||
|
|
||||||
# 状态标签
|
# 状态标签 (移动到最底部)
|
||||||
self.status_label = tk.Label(root, text="Initializing...", anchor="w", fg="grey")
|
self.status_label = tk.Label(root, text="Initializing...", anchor="w", fg="grey")
|
||||||
self.status_label.pack(side=tk.BOTTOM, fill=tk.X, padx=5, pady=2)
|
self.status_label.pack(side=tk.BOTTOM, fill=tk.X, padx=10, pady=(0, 5)) # 调整边距
|
||||||
|
|
||||||
# Matplotlib 图表设置 (用于第一个选项卡)
|
# Matplotlib 图表设置 (用于第一个选项卡)
|
||||||
self.fig = Figure(figsize=(5, 4), dpi=100)
|
self.fig = Figure(figsize=(5, 4), dpi=100)
|
||||||
@@ -81,6 +114,16 @@ class InterestMonitorApp:
|
|||||||
self.stream_selector.pack(side=tk.LEFT, fill=tk.X, expand=True)
|
self.stream_selector.pack(side=tk.LEFT, fill=tk.X, expand=True)
|
||||||
self.stream_selector.bind("<<ComboboxSelected>>", self.on_stream_selected)
|
self.stream_selector.bind("<<ComboboxSelected>>", self.on_stream_selected)
|
||||||
|
|
||||||
|
# --- 新增:单个流详情显示区域 ---
|
||||||
|
self.single_stream_details_frame = ttk.Frame(self.frame_single, padding="5 5 5 0")
|
||||||
|
self.single_stream_details_frame.pack(side=tk.TOP, fill=tk.X, pady=(0, 5))
|
||||||
|
|
||||||
|
ttk.Label(self.single_stream_details_frame, textvariable=self.single_stream_sub_mind).pack(side=tk.LEFT, padx=5)
|
||||||
|
ttk.Label(self.single_stream_details_frame, textvariable=self.single_stream_chat_state).pack(side=tk.LEFT, padx=5)
|
||||||
|
ttk.Label(self.single_stream_details_frame, textvariable=self.single_stream_threshold).pack(side=tk.LEFT, padx=5)
|
||||||
|
ttk.Label(self.single_stream_details_frame, textvariable=self.single_stream_last_active).pack(side=tk.LEFT, padx=5)
|
||||||
|
ttk.Label(self.single_stream_details_frame, textvariable=self.single_stream_last_interaction).pack(side=tk.LEFT, padx=5)
|
||||||
|
|
||||||
# Matplotlib 图表设置 (用于第二个选项卡)
|
# Matplotlib 图表设置 (用于第二个选项卡)
|
||||||
self.fig_single = Figure(figsize=(5, 4), dpi=100)
|
self.fig_single = Figure(figsize=(5, 4), dpi=100)
|
||||||
# 修改:创建两个子图,一个显示兴趣度,一个显示概率
|
# 修改:创建两个子图,一个显示兴趣度,一个显示概率
|
||||||
@@ -116,6 +159,11 @@ class InterestMonitorApp:
|
|||||||
new_stream_history = {}
|
new_stream_history = {}
|
||||||
new_stream_display_names = {}
|
new_stream_display_names = {}
|
||||||
new_probability_history = {} # <--- 重置概率历史
|
new_probability_history = {} # <--- 重置概率历史
|
||||||
|
# --- 新增:重置其他子流状态 --- (如果需要的话,但通常覆盖即可)
|
||||||
|
# self.stream_sub_minds = {}
|
||||||
|
# self.stream_chat_states = {}
|
||||||
|
# ... 等等 ...
|
||||||
|
|
||||||
read_count = 0
|
read_count = 0
|
||||||
error_count = 0
|
error_count = 0
|
||||||
# *** Calculate the timestamp threshold for the last 30 minutes ***
|
# *** Calculate the timestamp threshold for the last 30 minutes ***
|
||||||
@@ -142,6 +190,10 @@ class InterestMonitorApp:
|
|||||||
error_count += 1
|
error_count += 1
|
||||||
continue # 跳过时间戳格式错误的行
|
continue # 跳过时间戳格式错误的行
|
||||||
|
|
||||||
|
# --- 新增:更新顶层信息 (使用最后一个有效行的数据) ---
|
||||||
|
self.latest_main_mind.set(log_entry.get("main_mind", self.latest_main_mind.get())) # 保留旧值如果缺失
|
||||||
|
self.latest_mai_state.set(log_entry.get("mai_state", self.latest_mai_state.get()))
|
||||||
|
self.latest_subflow_count.set(log_entry.get("subflow_count", self.latest_subflow_count.get()))
|
||||||
|
|
||||||
# --- 修改开始:迭代 subflows ---
|
# --- 修改开始:迭代 subflows ---
|
||||||
subflows = log_entry.get("subflows")
|
subflows = log_entry.get("subflows")
|
||||||
@@ -179,6 +231,13 @@ class InterestMonitorApp:
|
|||||||
# *** 存储此 stream_id 最新的显示名称 ***
|
# *** 存储此 stream_id 最新的显示名称 ***
|
||||||
new_stream_display_names[stream_id] = group_name
|
new_stream_display_names[stream_id] = group_name
|
||||||
|
|
||||||
|
# --- 新增:存储其他子流信息 ---
|
||||||
|
self.stream_sub_minds[stream_id] = subflow_entry.get("sub_mind", "N/A")
|
||||||
|
self.stream_chat_states[stream_id] = subflow_entry.get("sub_chat_state", "N/A")
|
||||||
|
self.stream_threshold_status[stream_id] = subflow_entry.get("is_above_threshold", False)
|
||||||
|
self.stream_last_active[stream_id] = subflow_entry.get("last_active_time") # 存储原始时间戳
|
||||||
|
self.stream_last_interaction[stream_id] = subflow_entry.get("last_interaction_time") # 存储原始时间戳
|
||||||
|
|
||||||
# 添加数据点 (使用顶层时间戳)
|
# 添加数据点 (使用顶层时间戳)
|
||||||
new_stream_history[stream_id].append((entry_timestamp, interest_level_float))
|
new_stream_history[stream_id].append((entry_timestamp, interest_level_float))
|
||||||
|
|
||||||
@@ -206,6 +265,16 @@ class InterestMonitorApp:
|
|||||||
self.stream_history = new_stream_history
|
self.stream_history = new_stream_history
|
||||||
self.stream_display_names = new_stream_display_names # *** Update display names ***
|
self.stream_display_names = new_stream_display_names # *** Update display names ***
|
||||||
self.probability_history = new_probability_history # <--- 更新概率历史
|
self.probability_history = new_probability_history # <--- 更新概率历史
|
||||||
|
# 清理不再存在的 stream_id 的附加信息 (可选,但保持一致性)
|
||||||
|
streams_to_remove = set(self.stream_sub_minds.keys()) - set(new_stream_history.keys())
|
||||||
|
for sid in streams_to_remove:
|
||||||
|
self.stream_sub_minds.pop(sid, None)
|
||||||
|
self.stream_chat_states.pop(sid, None)
|
||||||
|
self.stream_threshold_status.pop(sid, None)
|
||||||
|
self.stream_last_active.pop(sid, None)
|
||||||
|
self.stream_last_interaction.pop(sid, None)
|
||||||
|
# 颜色和显示名称也应该清理,但当前逻辑是保留旧颜色
|
||||||
|
# self.stream_colors.pop(sid, None)
|
||||||
status_msg = f"Data loaded at {datetime.now().strftime('%H:%M:%S')}. Lines read: {read_count}."
|
status_msg = f"Data loaded at {datetime.now().strftime('%H:%M:%S')}. Lines read: {read_count}."
|
||||||
if error_count > 0:
|
if error_count > 0:
|
||||||
status_msg += f" Skipped {error_count} invalid lines."
|
status_msg += f" Skipped {error_count} invalid lines."
|
||||||
@@ -409,9 +478,45 @@ class InterestMonitorApp:
|
|||||||
self.ax_single_interest.set_xlim(one_hour_ago, now)
|
self.ax_single_interest.set_xlim(one_hour_ago, now)
|
||||||
# self.ax_single_probability.set_xlim(one_hour_ago, now) # sharex 会自动同步
|
# self.ax_single_probability.set_xlim(one_hour_ago, now) # sharex 会自动同步
|
||||||
|
|
||||||
|
# --- 新增:更新单个流的详细信息标签 ---
|
||||||
|
self.update_single_stream_details(selected_sid)
|
||||||
|
|
||||||
# --- 新增:重新绘制画布 ---
|
# --- 新增:重新绘制画布 ---
|
||||||
self.canvas_single.draw()
|
self.canvas_single.draw()
|
||||||
|
|
||||||
|
def format_timestamp(self, ts):
|
||||||
|
"""辅助函数:格式化时间戳,处理 None 或无效值"""
|
||||||
|
if ts is None:
|
||||||
|
return "N/A"
|
||||||
|
try:
|
||||||
|
# 假设 ts 是 float 类型的时间戳
|
||||||
|
dt_object = datetime.fromtimestamp(float(ts))
|
||||||
|
return dt_object.strftime("%Y-%m-%d %H:%M:%S")
|
||||||
|
except (ValueError, TypeError):
|
||||||
|
return "Invalid Time"
|
||||||
|
|
||||||
|
def update_single_stream_details(self, stream_id):
|
||||||
|
"""更新单个流详情区域的标签内容"""
|
||||||
|
if stream_id:
|
||||||
|
sub_mind = self.stream_sub_minds.get(stream_id, "N/A")
|
||||||
|
chat_state = self.stream_chat_states.get(stream_id, "N/A")
|
||||||
|
threshold = self.stream_threshold_status.get(stream_id, False)
|
||||||
|
last_active_ts = self.stream_last_active.get(stream_id)
|
||||||
|
last_interaction_ts = self.stream_last_interaction.get(stream_id)
|
||||||
|
|
||||||
|
self.single_stream_sub_mind.set(f"想法: {sub_mind}")
|
||||||
|
self.single_stream_chat_state.set(f"状态: {chat_state}")
|
||||||
|
self.single_stream_threshold.set(f"阈值以上: {'是' if threshold else '否'}")
|
||||||
|
self.single_stream_last_active.set(f"最后活跃: {self.format_timestamp(last_active_ts)}")
|
||||||
|
self.single_stream_last_interaction.set(f"最后交互: {self.format_timestamp(last_interaction_ts)}")
|
||||||
|
else:
|
||||||
|
# 如果没有选择流,则清空详情
|
||||||
|
self.single_stream_sub_mind.set("想法: N/A")
|
||||||
|
self.single_stream_chat_state.set("状态: N/A")
|
||||||
|
self.single_stream_threshold.set("阈值: N/A")
|
||||||
|
self.single_stream_last_active.set("活跃: N/A")
|
||||||
|
self.single_stream_last_interaction.set("交互: N/A")
|
||||||
|
|
||||||
def update_display(self):
|
def update_display(self):
|
||||||
"""主更新循环"""
|
"""主更新循环"""
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -230,7 +230,7 @@ class NormalChat:
|
|||||||
willing_log = f"[回复意愿:{await willing_manager.get_willing(self.stream_id):.2f}]" if is_willing else ""
|
willing_log = f"[回复意愿:{await willing_manager.get_willing(self.stream_id):.2f}]" if is_willing else ""
|
||||||
logger.info(
|
logger.info(
|
||||||
f"[{current_time}][{mes_name}]"
|
f"[{current_time}][{mes_name}]"
|
||||||
f"{self.chat_stream.user_info.user_nickname}:" # 使用 self.chat_stream
|
f"{message.message_info.user_info.user_nickname}:" # 使用 self.chat_stream
|
||||||
f"{message.processed_plain_text}{willing_log}[概率:{reply_probability * 100:.1f}%]"
|
f"{message.processed_plain_text}{willing_log}[概率:{reply_probability * 100:.1f}%]"
|
||||||
)
|
)
|
||||||
do_reply = False
|
do_reply = False
|
||||||
|
|||||||
Reference in New Issue
Block a user