From ee4a2f6e72a81fcdb46122a7bb8856b80aca9891 Mon Sep 17 00:00:00 2001
From: SengokuCola <1026294844@qq.com>
Date: Wed, 26 Mar 2025 21:31:32 +0800
Subject: [PATCH 01/11] =?UTF-8?q?better=20=E6=97=A5=E7=A8=8B=E7=B3=BB?=
=?UTF-8?q?=E7=BB=9F2.0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
README.md | 2 +-
src/plugins/schedule/offline_llm.py | 52 +-----------
.../schedule/schedule_generator_pro.py | 82 ++++++++++++++-----
3 files changed, 64 insertions(+), 72 deletions(-)
diff --git a/README.md b/README.md
index b005bc18..8dfbbe43 100644
--- a/README.md
+++ b/README.md
@@ -130,7 +130,7 @@ MaiMBot是一个开源项目,我们非常欢迎你的参与。你的贡献,
### 💬交流群
- [五群](https://qm.qq.com/q/JxvHZnxyec) 1022489779(开发和建议相关讨论)不一定有空回复,会优先写文档和代码
- [一群](https://qm.qq.com/q/VQ3XZrWgMs) 766798517 【已满】(开发和建议相关讨论)不一定有空回复,会优先写文档和代码
-- [二群](https://qm.qq.com/q/RzmCiRtHEW) 571780722 【已满】(开发和建议相关讨论)不一定有空回复,会优先写文档和代码
+- [二群](https://qm.qq.com/q/RzmCiRtHEW) 571780722(开发和建议相关讨论)不一定有空回复,会优先写文档和代码
- [三群](https://qm.qq.com/q/wlH5eT8OmQ) 1035228475【已满】(开发和建议相关讨论)不一定有空回复,会优先写文档和代码
- [四群](https://qm.qq.com/q/wlH5eT8OmQ) 729957033【已满】(开发和建议相关讨论)不一定有空回复,会优先写文档和代码
diff --git a/src/plugins/schedule/offline_llm.py b/src/plugins/schedule/offline_llm.py
index e4dc23f9..5c56d9e0 100644
--- a/src/plugins/schedule/offline_llm.py
+++ b/src/plugins/schedule/offline_llm.py
@@ -22,57 +22,7 @@ class LLMModel:
logger.info(f"API URL: {self.base_url}") # 使用 logger 记录 base_url
- def generate_response(self, prompt: str) -> Union[str, Tuple[str, str]]:
- """根据输入的提示生成模型的响应"""
- headers = {"Authorization": f"Bearer {self.api_key}", "Content-Type": "application/json"}
-
- # 构建请求体
- data = {
- "model": self.model_name,
- "messages": [{"role": "user", "content": prompt}],
- "temperature": 0.5,
- **self.params,
- }
-
- # 发送请求到完整的 chat/completions 端点
- api_url = f"{self.base_url.rstrip('/')}/chat/completions"
- logger.info(f"Request URL: {api_url}") # 记录请求的 URL
-
- max_retries = 3
- base_wait_time = 15 # 基础等待时间(秒)
-
- for retry in range(max_retries):
- try:
- response = requests.post(api_url, headers=headers, json=data)
-
- if response.status_code == 429:
- wait_time = base_wait_time * (2**retry) # 指数退避
- logger.warning(f"遇到请求限制(429),等待{wait_time}秒后重试...")
- time.sleep(wait_time)
- continue
-
- response.raise_for_status() # 检查其他响应状态
-
- result = response.json()
- if "choices" in result and len(result["choices"]) > 0:
- content = result["choices"][0]["message"]["content"]
- reasoning_content = result["choices"][0]["message"].get("reasoning_content", "")
- return content, reasoning_content
- return "没有返回结果", ""
-
- except Exception as e:
- if retry < max_retries - 1: # 如果还有重试机会
- wait_time = base_wait_time * (2**retry)
- logger.error(f"[回复]请求失败,等待{wait_time}秒后重试... 错误: {str(e)}")
- time.sleep(wait_time)
- else:
- logger.error(f"请求失败: {str(e)}")
- return f"请求失败: {str(e)}", ""
-
- logger.error("达到最大重试次数,请求仍然失败")
- return "达到最大重试次数,请求仍然失败", ""
-
- async def generate_response_async(self, prompt: str) -> Union[str, Tuple[str, str]]:
+ async def generate_response_async(self, prompt: str) -> str:
"""异步方式根据输入的提示生成模型的响应"""
headers = {"Authorization": f"Bearer {self.api_key}", "Content-Type": "application/json"}
diff --git a/src/plugins/schedule/schedule_generator_pro.py b/src/plugins/schedule/schedule_generator_pro.py
index 5a2c2a68..ceaf2afd 100644
--- a/src/plugins/schedule/schedule_generator_pro.py
+++ b/src/plugins/schedule/schedule_generator_pro.py
@@ -20,7 +20,7 @@ class ScheduleGenerator:
def __init__(self, name: str = "bot_name", personality: str = "你是一个爱国爱党的新时代青年", behavior: str = "你非常外向,喜欢尝试新事物和人交流"):
# 使用离线LLM模型
- self.llm_scheduler = LLMModel(model_name="Pro/deepseek-ai/DeepSeek-V3", temperature=0.9)
+ self.llm_scheduler = LLMModel(model_name="Qwen/Qwen2.5-32B-Instruct", temperature=0.9)
self.today_schedule_text = ""
self.today_done_list = []
@@ -33,6 +33,8 @@ class ScheduleGenerator:
self.behavior = behavior
self.start_time = datetime.datetime.now()
+
+ self.schedule_doing_update_interval = 60 #最好大于60
async def mai_schedule_start(self):
"""启动日程系统,每5分钟执行一次move_doing,并在日期变化时重新检查日程"""
@@ -43,6 +45,8 @@ class ScheduleGenerator:
self.print_schedule()
while True:
+ print(self.get_current_num_task(1, True))
+
current_time = datetime.datetime.now()
# 检查是否需要重新生成日程(日期变化)
@@ -56,8 +60,7 @@ class ScheduleGenerator:
current_activity = await self.move_doing()
logger.info(f"当前活动: {current_activity}")
- # 等待5分钟
- await asyncio.sleep(300) # 300秒 = 5分钟
+ await asyncio.sleep(self.schedule_doing_update_interval)
except Exception as e:
logger.error(f"日程系统运行时出错: {str(e)}")
@@ -79,6 +82,8 @@ class ScheduleGenerator:
# 检查今天的日程
self.today_schedule_text, self.today_done_list = self.load_schedule_from_db(today)
+ if not self.today_done_list:
+ self.today_done_list = []
if not self.today_schedule_text:
logger.info(f"{today.strftime('%Y-%m-%d')}的日程不存在,准备生成新的日程")
self.today_schedule_text = await self.generate_daily_schedule(target_date=today)
@@ -98,10 +103,16 @@ class ScheduleGenerator:
def construct_doing_prompt(self,time: datetime.datetime):
now_time = time.strftime("%H:%M")
- previous_doing = self.today_done_list[-20:] if len(self.today_done_list) > 20 else self.today_done_list
+ if self.today_done_list:
+ previous_doing = self.get_current_num_task(10, True)
+ print(previous_doing)
+ else:
+ previous_doing = "我没做什么事情"
+
+
prompt = f"我是{self.name},{self.personality},{self.behavior}"
prompt += f"我今天的日程是:{self.today_schedule_text}\n"
- prompt += f"我之前做了的事情是:{previous_doing}\n"
+ prompt += f"我之前做了的事情是:{previous_doing},从之前到现在已经过去了{self.schedule_doing_update_interval/60}分钟了\n"
prompt += f"现在是{now_time},结合我的个人特点和行为习惯,"
prompt += "推测我现在做什么,具体一些,详细一些\n"
prompt += "直接返回我在做的事情,不要输出其他内容:"
@@ -110,7 +121,7 @@ class ScheduleGenerator:
async def generate_daily_schedule(
self, target_date: datetime.datetime = None,) -> Dict[str, str]:
daytime_prompt = self.construct_daytime_prompt(target_date)
- daytime_response, _ = await self.llm_scheduler.generate_response(daytime_prompt)
+ daytime_response,_ = await self.llm_scheduler.generate_response_async(daytime_prompt)
return daytime_response
def _time_diff(self, time1: str, time2: str) -> int:
@@ -160,15 +171,54 @@ class ScheduleGenerator:
current_time = datetime.datetime.now()
time_str = current_time.strftime("%H:%M")
doing_prompt = self.construct_doing_prompt(current_time)
- doing_response, _ = await self.llm_scheduler.generate_response(doing_prompt)
- self.today_done_list.append(current_time,time_str + "在" + doing_response)
+ doing_response,_ = await self.llm_scheduler.generate_response_async(doing_prompt)
+ self.today_done_list.append((current_time, time_str + "时," + doing_response))
await self.update_today_done_list()
return doing_response
+ async def get_task_from_time_to_time(self, start_time: str, end_time: str):
+ """获取指定时间范围内的任务列表
+
+ Args:
+ start_time (str): 开始时间,格式为"HH:MM"
+ end_time (str): 结束时间,格式为"HH:MM"
+
+ Returns:
+ list: 时间范围内的任务列表
+ """
+ result = []
+ for task in self.today_done_list:
+ task_time = task[0] # 获取任务的时间戳
+ task_time_str = task_time.strftime("%H:%M")
+
+ # 检查任务时间是否在指定范围内
+ if self._time_diff(start_time, task_time_str) >= 0 and self._time_diff(task_time_str, end_time) >= 0:
+ result.append(task)
+
+ return result
-
+ def get_current_num_task(self, num=1, time_info = False):
+ """获取最新加入的指定数量的日程
+
+ Args:
+ num (int): 需要获取的日程数量,默认为1
+
+ Returns:
+ list: 最新加入的日程列表
+ """
+ if not self.today_done_list:
+ return []
+
+ # 确保num不超过列表长度
+ num = min(num, len(self.today_done_list))
+ pre_doing = ""
+ for doing in self.today_done_list[-num:]:
+ pre_doing += doing[1]
+
+ # 返回最新的num条日程
+ return pre_doing
def save_today_schedule_to_db(self):
"""保存日程到数据库,同时初始化 today_done_list"""
@@ -200,18 +250,10 @@ class ScheduleGenerator:
async def main():
# 使用示例
- scheduler = ScheduleGenerator(name="麦麦", personality="你叫麦麦,你19岁,是一个大二的女大学生,你有一头黑色短发,你会刷贴吧,你现在在学习心理学", behavior="你比较内向")
- await scheduler.check_and_create_today_schedule()
- scheduler.print_schedule()
- print("\n当前任务:")
- print(await scheduler.get_current_task())
+ scheduler = ScheduleGenerator(name="麦麦", personality="你叫麦麦,你19岁,是一个大二的女大学生,你有一头黑色短发,你会刷贴吧,你现在在学习心理学", behavior="你比较内向,一般熬夜比较晚,然后第二天早上10点起床吃早午饭")
+ await scheduler.mai_schedule_start()
+
- print("昨天日程:")
- print(scheduler.yesterday_schedule)
- print("今天日程:")
- print(scheduler.today_schedule)
- print("明天日程:")
- print(scheduler.tomorrow_schedule)
# 当作为组件导入时使用的实例
bot_schedule = ScheduleGenerator()
From 572bffc27355d56c83ff691b42793305bb6c701a Mon Sep 17 00:00:00 2001
From: SengokuCola <1026294844@qq.com>
Date: Wed, 26 Mar 2025 22:42:19 +0800
Subject: [PATCH 02/11] =?UTF-8?q?better:=E6=97=A5=E5=BF=97=E7=B3=BB?=
=?UTF-8?q?=E7=BB=9F=E7=8E=B0=E5=B7=B2=E5=8F=AF=E4=BB=A5=E5=8A=A8=E6=80=81?=
=?UTF-8?q?=E6=9B=B4=E6=96=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/common/logger.py | 18 +
src/plugins/chat/__init__.py | 22 +-
src/plugins/chat/config.py | 3 +
src/plugins/chat/llm_generator.py | 6 +-
src/plugins/chat/prompt_builder.py | 6 +-
src/plugins/schedule/offline_llm.py | 2 +-
src/plugins/schedule/schedule_generator.py | 387 +++++++++++-------
.../schedule/schedule_generator_pro.py | 264 ------------
src/think_flow_demo/current_mind.py | 6 +-
src/think_flow_demo/heartflow.py | 9 +-
template/bot_config_template.toml | 1 +
11 files changed, 296 insertions(+), 428 deletions(-)
delete mode 100644 src/plugins/schedule/schedule_generator_pro.py
diff --git a/src/common/logger.py b/src/common/logger.py
index 45d6f415..b910427b 100644
--- a/src/common/logger.py
+++ b/src/common/logger.py
@@ -122,6 +122,23 @@ SENDER_STYLE_CONFIG = {
},
}
+SCHEDULE_STYLE_CONFIG = {
+ "advanced": {
+ "console_format": (
+ "{time:YYYY-MM-DD HH:mm:ss} | "
+ "{level: <8} | "
+ "{extra[module]: <12} | "
+ "在干嘛 | "
+ "{message}"
+ ),
+ "file_format": ("{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 在干嘛 | {message}"),
+ },
+ "simple": {
+ "console_format": ("{time:MM-DD HH:mm} | 在干嘛 | {message}"),
+ "file_format": ("{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 在干嘛 | {message}"),
+ },
+}
+
LLM_STYLE_CONFIG = {
"advanced": {
"console_format": (
@@ -183,6 +200,7 @@ SENDER_STYLE_CONFIG = SENDER_STYLE_CONFIG["simple"] if SIMPLE_OUTPUT else SENDER
LLM_STYLE_CONFIG = LLM_STYLE_CONFIG["simple"] if SIMPLE_OUTPUT else LLM_STYLE_CONFIG["advanced"]
CHAT_STYLE_CONFIG = CHAT_STYLE_CONFIG["simple"] if SIMPLE_OUTPUT else CHAT_STYLE_CONFIG["advanced"]
MOOD_STYLE_CONFIG = MOOD_STYLE_CONFIG["simple"] if SIMPLE_OUTPUT else MOOD_STYLE_CONFIG["advanced"]
+SCHEDULE_STYLE_CONFIG = SCHEDULE_STYLE_CONFIG["simple"] if SIMPLE_OUTPUT else SCHEDULE_STYLE_CONFIG["advanced"]
def is_registered_module(record: dict) -> bool:
"""检查是否为已注册的模块"""
diff --git a/src/plugins/chat/__init__.py b/src/plugins/chat/__init__.py
index f51184a7..8bbb16bf 100644
--- a/src/plugins/chat/__init__.py
+++ b/src/plugins/chat/__init__.py
@@ -79,10 +79,14 @@ async def start_background_tasks():
# 只启动表情包管理任务
asyncio.create_task(emoji_manager.start_periodic_check())
- await bot_schedule.initialize()
- bot_schedule.print_schedule()
+@driver.on_startup
+async def init_schedule():
+ """在 NoneBot2 启动时初始化日程系统"""
+ bot_schedule.initialize(name=global_config.BOT_NICKNAME, personality=global_config.PROMPT_PERSONALITY, behavior=global_config.PROMPT_SCHEDULE_GEN, interval=global_config.SCHEDULE_DOING_UPDATE_INTERVAL)
+ asyncio.create_task(bot_schedule.mai_schedule_start())
+
@driver.on_startup
async def init_relationships():
"""在 NoneBot2 启动时初始化关系管理器"""
@@ -157,13 +161,13 @@ async def print_mood_task():
mood_manager.print_mood_status()
-@scheduler.scheduled_job("interval", seconds=7200, id="generate_schedule")
-async def generate_schedule_task():
- """每2小时尝试生成一次日程"""
- logger.debug("尝试生成日程")
- await bot_schedule.initialize()
- if not bot_schedule.enable_output:
- bot_schedule.print_schedule()
+# @scheduler.scheduled_job("interval", seconds=7200, id="generate_schedule")
+# async def generate_schedule_task():
+# """每2小时尝试生成一次日程"""
+# logger.debug("尝试生成日程")
+# await bot_schedule.initialize()
+# if not bot_schedule.enable_output:
+# bot_schedule.print_schedule()
@scheduler.scheduled_job("interval", seconds=3600, id="remove_recalled_message")
diff --git a/src/plugins/chat/config.py b/src/plugins/chat/config.py
index 2d9badbc..1ac2a7ea 100644
--- a/src/plugins/chat/config.py
+++ b/src/plugins/chat/config.py
@@ -42,6 +42,7 @@ class BotConfig:
# schedule
ENABLE_SCHEDULE_GEN: bool = False # 是否启用日程生成
PROMPT_SCHEDULE_GEN = "无日程"
+ SCHEDULE_DOING_UPDATE_INTERVAL: int = 300 # 日程表更新间隔 单位秒
# message
MAX_CONTEXT_SIZE: int = 15 # 上下文最大消息数
@@ -219,6 +220,8 @@ class BotConfig:
schedule_config = parent["schedule"]
config.ENABLE_SCHEDULE_GEN = schedule_config.get("enable_schedule_gen", config.ENABLE_SCHEDULE_GEN)
config.PROMPT_SCHEDULE_GEN = schedule_config.get("prompt_schedule_gen", config.PROMPT_SCHEDULE_GEN)
+ config.SCHEDULE_DOING_UPDATE_INTERVAL = schedule_config.get(
+ "schedule_doing_update_interval", config.SCHEDULE_DOING_UPDATE_INTERVAL)
logger.info(
f"载入自定义日程prompt:{schedule_config.get('prompt_schedule_gen', config.PROMPT_SCHEDULE_GEN)}")
diff --git a/src/plugins/chat/llm_generator.py b/src/plugins/chat/llm_generator.py
index 316260c8..7b032104 100644
--- a/src/plugins/chat/llm_generator.py
+++ b/src/plugins/chat/llm_generator.py
@@ -51,13 +51,13 @@ class ResponseGenerator:
# 从global_config中获取模型概率值并选择模型
rand = random.random()
if rand < global_config.MODEL_R1_PROBABILITY:
- self.current_model_type = "r1"
+ self.current_model_type = "深深地"
current_model = self.model_r1
elif rand < global_config.MODEL_R1_PROBABILITY + global_config.MODEL_V3_PROBABILITY:
- self.current_model_type = "v3"
+ self.current_model_type = "浅浅的"
current_model = self.model_v3
else:
- self.current_model_type = "r1_distill"
+ self.current_model_type = "又浅又浅的"
current_model = self.model_r1_distill
logger.info(f"{global_config.BOT_NICKNAME}{self.current_model_type}思考中")
diff --git a/src/plugins/chat/prompt_builder.py b/src/plugins/chat/prompt_builder.py
index ef070ed2..283ea0ea 100644
--- a/src/plugins/chat/prompt_builder.py
+++ b/src/plugins/chat/prompt_builder.py
@@ -57,9 +57,7 @@ class PromptBuilder:
mood_prompt = mood_manager.get_prompt()
# 日程构建
- # current_date = time.strftime("%Y-%m-%d", time.localtime())
- # current_time = time.strftime("%H:%M:%S", time.localtime())
- # bot_schedule_now_time, bot_schedule_now_activity = bot_schedule.get_current_task()
+ schedule_prompt = f'''你现在正在做的事情是:{bot_schedule.get_current_num_task(num = 1,time_info = False)}'''
# 获取聊天上下文
chat_in_group = True
@@ -173,8 +171,6 @@ class PromptBuilder:
prompt_check_if_response = ""
- # print(prompt)
-
return prompt, prompt_check_if_response
def _build_initiative_prompt_select(self, group_id, probability_1=0.8, probability_2=0.1):
diff --git a/src/plugins/schedule/offline_llm.py b/src/plugins/schedule/offline_llm.py
index 5c56d9e0..f274740f 100644
--- a/src/plugins/schedule/offline_llm.py
+++ b/src/plugins/schedule/offline_llm.py
@@ -30,7 +30,7 @@ class LLMModel:
data = {
"model": self.model_name,
"messages": [{"role": "user", "content": prompt}],
- "temperature": 0.5,
+ "temperature": 0.7,
**self.params,
}
diff --git a/src/plugins/schedule/schedule_generator.py b/src/plugins/schedule/schedule_generator.py
index b26b2954..d39b0517 100644
--- a/src/plugins/schedule/schedule_generator.py
+++ b/src/plugins/schedule/schedule_generator.py
@@ -1,159 +1,149 @@
import datetime
-import json
-import re
-from typing import Dict, Union
-
-from nonebot import get_driver
-
+import os
+import sys
+from typing import Dict
+import asyncio
# 添加项目根目录到 Python 路径
+root_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "../../.."))
+sys.path.append(root_path)
-from src.plugins.chat.config import global_config
-from ...common.database import db # 使用正确的导入语法
-from ..models.utils_model import LLM_request
-from src.common.logger import get_module_logger
+from src.common.database import db # noqa: E402
+from src.common.logger import get_module_logger, SCHEDULE_STYLE_CONFIG, LogConfig # noqa: E402
+from src.plugins.models.utils_model import LLM_request # noqa: E402
+from src.plugins.chat.config import global_config # noqa: E402
-logger = get_module_logger("scheduler")
-driver = get_driver()
-config = driver.config
+schedule_config = LogConfig(
+ # 使用海马体专用样式
+ console_format=SCHEDULE_STYLE_CONFIG["console_format"],
+ file_format=SCHEDULE_STYLE_CONFIG["file_format"],
+)
+logger = get_module_logger("scheduler", config=schedule_config)
class ScheduleGenerator:
- enable_output: bool = True
+ # enable_output: bool = True
- def __init__(self):
- # 根据global_config.llm_normal这一字典配置指定模型
- # self.llm_scheduler = LLMModel(model = global_config.llm_normal,temperature=0.9)
- self.llm_scheduler = LLM_request(model=global_config.llm_normal, temperature=0.9, request_type="scheduler")
+ def __init__(self, ):
+ # 使用离线LLM模型
+ self.llm_scheduler_all = LLM_request(
+ model= global_config.llm_reasoning, temperature=0.9, max_tokens=2048,request_type="schedule")
+ self.llm_scheduler_doing = LLM_request(
+ model= global_config.llm_normal, temperature=0.9, max_tokens=2048,request_type="schedule")
+
self.today_schedule_text = ""
- self.today_schedule = {}
- self.tomorrow_schedule_text = ""
- self.tomorrow_schedule = {}
+ self.today_done_list = []
+
self.yesterday_schedule_text = ""
- self.yesterday_schedule = {}
+ self.yesterday_done_list = []
- async def initialize(self):
+ self.name = ""
+ self.personality = ""
+ self.behavior = ""
+
+ self.start_time = datetime.datetime.now()
+
+ self.schedule_doing_update_interval = 60 #最好大于60
+
+ def initialize(self,name: str = "bot_name", personality: str = "你是一个爱国爱党的新时代青年", behavior: str = "你非常外向,喜欢尝试新事物和人交流",interval: int = 60):
+ """初始化日程系统"""
+ self.name = name
+ self.behavior = behavior
+ self.schedule_doing_update_interval = interval
+
+ for pers in personality:
+ self.personality += pers + "\n"
+
+
+ async def mai_schedule_start(self):
+ """启动日程系统,每5分钟执行一次move_doing,并在日期变化时重新检查日程"""
+ try:
+ logger.info(f"日程系统启动/刷新时间: {self.start_time.strftime('%Y-%m-%d %H:%M:%S')}")
+ # 初始化日程
+ await self.check_and_create_today_schedule()
+ self.print_schedule()
+
+ while True:
+ print(self.get_current_num_task(1, True))
+
+ current_time = datetime.datetime.now()
+
+ # 检查是否需要重新生成日程(日期变化)
+ if current_time.date() != self.start_time.date():
+ logger.info("检测到日期变化,重新生成日程")
+ self.start_time = current_time
+ await self.check_and_create_today_schedule()
+ self.print_schedule()
+
+ # 执行当前活动
+ current_activity = await self.move_doing(mind_thinking="")
+ logger.info(f"当前活动: {current_activity}")
+
+ await asyncio.sleep(self.schedule_doing_update_interval)
+
+ except Exception as e:
+ logger.error(f"日程系统运行时出错: {str(e)}")
+ logger.exception("详细错误信息:")
+
+ async def check_and_create_today_schedule(self):
+ """检查昨天的日程,并确保今天有日程安排
+
+ Returns:
+ tuple: (today_schedule_text, today_schedule) 今天的日程文本和解析后的日程字典
+ """
today = datetime.datetime.now()
- tomorrow = datetime.datetime.now() + datetime.timedelta(days=1)
- yesterday = datetime.datetime.now() - datetime.timedelta(days=1)
+ yesterday = today - datetime.timedelta(days=1)
+
+ # 先检查昨天的日程
+ self.yesterday_schedule_text, self.yesterday_done_list = self.load_schedule_from_db(yesterday)
+ if self.yesterday_schedule_text:
+ logger.debug(f"已加载{yesterday.strftime('%Y-%m-%d')}的日程")
+
+ # 检查今天的日程
+ self.today_schedule_text, self.today_done_list = self.load_schedule_from_db(today)
+ if not self.today_done_list:
+ self.today_done_list = []
+ if not self.today_schedule_text:
+ logger.info(f"{today.strftime('%Y-%m-%d')}的日程不存在,准备生成新的日程")
+ self.today_schedule_text = await self.generate_daily_schedule(target_date=today)
- self.today_schedule_text, self.today_schedule = await self.generate_daily_schedule(target_date=today)
- self.tomorrow_schedule_text, self.tomorrow_schedule = await self.generate_daily_schedule(
- target_date=tomorrow, read_only=True
- )
- self.yesterday_schedule_text, self.yesterday_schedule = await self.generate_daily_schedule(
- target_date=yesterday, read_only=True
- )
-
- async def generate_daily_schedule(
- self, target_date: datetime.datetime = None, read_only: bool = False
- ) -> Dict[str, str]:
+ self.save_today_schedule_to_db()
+
+ def construct_daytime_prompt(self, target_date: datetime.datetime):
date_str = target_date.strftime("%Y-%m-%d")
weekday = target_date.strftime("%A")
- schedule_text = str
-
- existing_schedule = db.schedule.find_one({"date": date_str})
- if existing_schedule:
- if self.enable_output:
- logger.debug(f"{date_str}的日程已存在:")
- schedule_text = existing_schedule["schedule"]
- # print(self.schedule_text)
-
- elif not read_only:
- logger.debug(f"{date_str}的日程不存在,准备生成新的日程。")
- prompt = (
- f"""我是{global_config.BOT_NICKNAME},{global_config.PROMPT_SCHEDULE_GEN},请为我生成{date_str}({weekday})的日程安排,包括:"""
- + """
- 1. 早上的学习和工作安排
- 2. 下午的活动和任务
- 3. 晚上的计划和休息时间
- 请按照时间顺序列出具体时间点和对应的活动,用一个时间点而不是时间段来表示时间,用JSON格式返回日程表,
- 仅返回内容,不要返回注释,不要添加任何markdown或代码块样式,时间采用24小时制,
- 格式为{"时间": "活动","时间": "活动",...}。"""
- )
-
- try:
- schedule_text, _, _ = await self.llm_scheduler.generate_response(prompt)
- db.schedule.insert_one({"date": date_str, "schedule": schedule_text})
- self.enable_output = True
- except Exception as e:
- logger.error(f"生成日程失败: {str(e)}")
- schedule_text = "生成日程时出错了"
- # print(self.schedule_text)
+ prompt = f"你是{self.name},{self.personality},{self.behavior}"
+ prompt += f"你昨天的日程是:{self.yesterday_schedule_text}\n"
+ prompt += f"请为你生成{date_str}({weekday})的日程安排,结合你的个人特点和行为习惯\n"
+ prompt += "推测你的日程安排,包括你一天都在做什么,有什么发现和思考,具体一些,详细一些,需要1500字以上,精确到每半个小时,记得写明时间\n"
+ prompt += "直接返回你的日程,不要输出其他内容:"
+ return prompt
+
+ def construct_doing_prompt(self,time: datetime.datetime,mind_thinking: str = ""):
+ now_time = time.strftime("%H:%M")
+ if self.today_done_list:
+ previous_doings = self.get_current_num_task(10, True)
+ # print(previous_doings)
else:
- if self.enable_output:
- logger.debug(f"{date_str}的日程不存在。")
- schedule_text = "忘了"
-
- return schedule_text, None
-
- schedule_form = self._parse_schedule(schedule_text)
- return schedule_text, schedule_form
-
- def _parse_schedule(self, schedule_text: str) -> Union[bool, Dict[str, str]]:
- """解析日程文本,转换为时间和活动的字典"""
- try:
- reg = r"\{(.|\r|\n)+\}"
- matched = re.search(reg, schedule_text)[0]
- schedule_dict = json.loads(matched)
- self._check_schedule_validity(schedule_dict)
- return schedule_dict
- except json.JSONDecodeError:
- logger.exception("解析日程失败: {}".format(schedule_text))
- return False
- except ValueError as e:
- logger.exception(f"解析日程失败: {str(e)}")
- return False
- except Exception as e:
- logger.exception(f"解析日程发生错误:{str(e)}")
- return False
-
- def _check_schedule_validity(self, schedule_dict: Dict[str, str]):
- """检查日程是否合法"""
- if not schedule_dict:
- return
- for time_str in schedule_dict.keys():
- try:
- self._parse_time(time_str)
- except ValueError:
- raise ValueError("日程时间格式不正确") from None
-
- def _parse_time(self, time_str: str) -> str:
- """解析时间字符串,转换为时间"""
- return datetime.datetime.strptime(time_str, "%H:%M")
-
- def get_current_task(self) -> str:
- """获取当前时间应该进行的任务"""
- current_time = datetime.datetime.now().strftime("%H:%M")
-
- # 找到最接近当前时间的任务
- closest_time = None
- min_diff = float("inf")
-
- # 检查今天的日程
- if not self.today_schedule:
- return "摸鱼"
- for time_str in self.today_schedule.keys():
- diff = abs(self._time_diff(current_time, time_str))
- if closest_time is None or diff < min_diff:
- closest_time = time_str
- min_diff = diff
-
- # 检查昨天的日程中的晚间任务
- if self.yesterday_schedule:
- for time_str in self.yesterday_schedule.keys():
- if time_str >= "20:00": # 只考虑晚上8点之后的任务
- # 计算与昨天这个时间点的差异(需要加24小时)
- diff = abs(self._time_diff(current_time, time_str))
- if diff < min_diff:
- closest_time = time_str
- min_diff = diff
- return closest_time, self.yesterday_schedule[closest_time]
-
- if closest_time:
- return closest_time, self.today_schedule[closest_time]
- return "摸鱼"
+ previous_doings = "你没做什么事情"
+
+
+ prompt = f"你是{self.name},{self.personality},{self.behavior}"
+ prompt += f"你今天的日程是:{self.today_schedule_text}\n"
+ if mind_thinking:
+ prompt += f"你脑子里在想:{mind_thinking}\n"
+ prompt += f"你之前做了的事情是:{previous_doings},从之前到现在已经过去了{self.schedule_doing_update_interval/60}分钟了\n"
+ prompt += f"现在是{now_time},结合你的个人特点和行为习惯,"
+ prompt += "推测你现在做什么,具体一些,详细一些\n"
+ prompt += "直接返回你在做的事情,不要输出其他内容:"
+ return prompt
+
+ async def generate_daily_schedule(
+ self, target_date: datetime.datetime = None,) -> Dict[str, str]:
+ daytime_prompt = self.construct_daytime_prompt(target_date)
+ daytime_response,_ = await self.llm_scheduler_all.generate_response_async(daytime_prompt)
+ return daytime_response
def _time_diff(self, time1: str, time2: str) -> int:
"""计算两个时间字符串之间的分钟差"""
@@ -174,14 +164,127 @@ class ScheduleGenerator:
def print_schedule(self):
"""打印完整的日程安排"""
- if not self._parse_schedule(self.today_schedule_text):
- logger.warning("今日日程有误,将在两小时后重新生成")
+ if not self.today_schedule_text:
+ logger.warning("今日日程有误,将在下次运行时重新生成")
db.schedule.delete_one({"date": datetime.datetime.now().strftime("%Y-%m-%d")})
else:
logger.info("=== 今日日程安排 ===")
- for time_str, activity in self.today_schedule.items():
- logger.info(f"时间[{time_str}]: 活动[{activity}]")
+ logger.info(self.today_schedule_text)
logger.info("==================")
self.enable_output = False
+
+ async def update_today_done_list(self):
+ # 更新数据库中的 today_done_list
+ today_str = datetime.datetime.now().strftime("%Y-%m-%d")
+ existing_schedule = db.schedule.find_one({"date": today_str})
+
+ if existing_schedule:
+ # 更新数据库中的 today_done_list
+ db.schedule.update_one(
+ {"date": today_str},
+ {"$set": {"today_done_list": self.today_done_list}}
+ )
+ logger.debug(f"已更新{today_str}的已完成活动列表")
+ else:
+ logger.warning(f"未找到{today_str}的日程记录")
+
+ async def move_doing(self,mind_thinking: str = ""):
+ current_time = datetime.datetime.now()
+ doing_prompt = self.construct_doing_prompt(current_time,mind_thinking)
+ doing_response,_ = await self.llm_scheduler_doing.generate_response_async(doing_prompt)
+ self.today_done_list.append((current_time,doing_response))
+
+ await self.update_today_done_list()
+
+ return doing_response
+
+ async def get_task_from_time_to_time(self, start_time: str, end_time: str):
+ """获取指定时间范围内的任务列表
+
+ Args:
+ start_time (str): 开始时间,格式为"HH:MM"
+ end_time (str): 结束时间,格式为"HH:MM"
+
+ Returns:
+ list: 时间范围内的任务列表
+ """
+ result = []
+ for task in self.today_done_list:
+ task_time = task[0] # 获取任务的时间戳
+ task_time_str = task_time.strftime("%H:%M")
+
+ # 检查任务时间是否在指定范围内
+ if self._time_diff(start_time, task_time_str) >= 0 and self._time_diff(task_time_str, end_time) >= 0:
+ result.append(task)
+
+ return result
+
+ def get_current_num_task(self, num=1, time_info = False):
+ """获取最新加入的指定数量的日程
+
+ Args:
+ num (int): 需要获取的日程数量,默认为1
+
+ Returns:
+ list: 最新加入的日程列表
+ """
+ if not self.today_done_list:
+ return []
+
+ # 确保num不超过列表长度
+ num = min(num, len(self.today_done_list))
+ pre_doings = ""
+ for doing in self.today_done_list[-num:]:
+
+ if time_info:
+ time_str = doing[0].strftime("%H:%M")
+ pre_doings += time_str + "时," + doing[1] + "\n"
+ else:
+ pre_doings += doing[1] + "\n"
+
+ # 返回最新的num条日程
+ return pre_doings
+
+ def save_today_schedule_to_db(self):
+ """保存日程到数据库,同时初始化 today_done_list"""
+ date_str = datetime.datetime.now().strftime("%Y-%m-%d")
+ schedule_data = {
+ "date": date_str,
+ "schedule": self.today_schedule_text,
+ "today_done_list": self.today_done_list if hasattr(self, 'today_done_list') else []
+ }
+ # 使用 upsert 操作,如果存在则更新,不存在则插入
+ db.schedule.update_one(
+ {"date": date_str},
+ {"$set": schedule_data},
+ upsert=True
+ )
+ logger.debug(f"已保存{date_str}的日程到数据库")
+
+ def load_schedule_from_db(self, date: datetime.datetime):
+ """从数据库加载日程,同时加载 today_done_list"""
+ date_str = date.strftime("%Y-%m-%d")
+ existing_schedule = db.schedule.find_one({"date": date_str})
+
+ if existing_schedule:
+ schedule_text = existing_schedule["schedule"]
+ return schedule_text, existing_schedule.get("today_done_list", [])
+ else:
+ logger.debug(f"{date_str}的日程不存在")
+ return None, None
+
+async def main():
+ # 使用示例
+ scheduler = ScheduleGenerator()
+ scheduler.initialize(name="麦麦", personality="你叫麦麦,你19岁,是一个大二的女大学生,你有一头黑色短发,你会刷贴吧,你现在在学习心理学", behavior="你比较内向,一般熬夜比较晚,然后第二天早上10点起床吃早午饭",interval=60)
+ await scheduler.mai_schedule_start()
+
+
+
# 当作为组件导入时使用的实例
bot_schedule = ScheduleGenerator()
+
+if __name__ == "__main__":
+ import asyncio
+ # 当直接运行此文件时执行
+ asyncio.run(main())
diff --git a/src/plugins/schedule/schedule_generator_pro.py b/src/plugins/schedule/schedule_generator_pro.py
deleted file mode 100644
index ceaf2afd..00000000
--- a/src/plugins/schedule/schedule_generator_pro.py
+++ /dev/null
@@ -1,264 +0,0 @@
-import datetime
-import json
-import re
-import os
-import sys
-from typing import Dict, Union
-# 添加项目根目录到 Python 路径
-root_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "../../.."))
-sys.path.append(root_path)
-
-from src.common.database import db # noqa: E402
-from src.common.logger import get_module_logger # noqa: E402
-from src.plugins.schedule.offline_llm import LLMModel # noqa: E402
-
-logger = get_module_logger("scheduler")
-
-
-class ScheduleGenerator:
- enable_output: bool = True
-
- def __init__(self, name: str = "bot_name", personality: str = "你是一个爱国爱党的新时代青年", behavior: str = "你非常外向,喜欢尝试新事物和人交流"):
- # 使用离线LLM模型
- self.llm_scheduler = LLMModel(model_name="Qwen/Qwen2.5-32B-Instruct", temperature=0.9)
-
- self.today_schedule_text = ""
- self.today_done_list = []
-
- self.yesterday_schedule_text = ""
- self.yesterday_done_list = []
-
- self.name = name
- self.personality = personality
- self.behavior = behavior
-
- self.start_time = datetime.datetime.now()
-
- self.schedule_doing_update_interval = 60 #最好大于60
-
- async def mai_schedule_start(self):
- """启动日程系统,每5分钟执行一次move_doing,并在日期变化时重新检查日程"""
- try:
- logger.info(f"日程系统启动/刷新时间: {self.start_time.strftime('%Y-%m-%d %H:%M:%S')}")
- # 初始化日程
- await self.check_and_create_today_schedule()
- self.print_schedule()
-
- while True:
- print(self.get_current_num_task(1, True))
-
- current_time = datetime.datetime.now()
-
- # 检查是否需要重新生成日程(日期变化)
- if current_time.date() != self.start_time.date():
- logger.info("检测到日期变化,重新生成日程")
- self.start_time = current_time
- await self.check_and_create_today_schedule()
- self.print_schedule()
-
- # 执行当前活动
- current_activity = await self.move_doing()
- logger.info(f"当前活动: {current_activity}")
-
- await asyncio.sleep(self.schedule_doing_update_interval)
-
- except Exception as e:
- logger.error(f"日程系统运行时出错: {str(e)}")
- logger.exception("详细错误信息:")
-
- async def check_and_create_today_schedule(self):
- """检查昨天的日程,并确保今天有日程安排
-
- Returns:
- tuple: (today_schedule_text, today_schedule) 今天的日程文本和解析后的日程字典
- """
- today = datetime.datetime.now()
- yesterday = today - datetime.timedelta(days=1)
-
- # 先检查昨天的日程
- self.yesterday_schedule_text, self.yesterday_done_list = self.load_schedule_from_db(yesterday)
- if self.yesterday_schedule_text:
- logger.debug(f"已加载{yesterday.strftime('%Y-%m-%d')}的日程")
-
- # 检查今天的日程
- self.today_schedule_text, self.today_done_list = self.load_schedule_from_db(today)
- if not self.today_done_list:
- self.today_done_list = []
- if not self.today_schedule_text:
- logger.info(f"{today.strftime('%Y-%m-%d')}的日程不存在,准备生成新的日程")
- self.today_schedule_text = await self.generate_daily_schedule(target_date=today)
-
- self.save_today_schedule_to_db()
-
- def construct_daytime_prompt(self, target_date: datetime.datetime):
- date_str = target_date.strftime("%Y-%m-%d")
- weekday = target_date.strftime("%A")
-
- prompt = f"我是{self.name},{self.personality},{self.behavior}"
- prompt += f"我昨天的日程是:{self.yesterday_schedule_text}\n"
- prompt += f"请为我生成{date_str}({weekday})的日程安排,结合我的个人特点和行为习惯\n"
- prompt += "推测我的日程安排,包括我一天都在做什么,有什么发现和思考,具体一些,详细一些,记得写明时间\n"
- prompt += "直接返回我的日程,不要输出其他内容:"
- return prompt
-
- def construct_doing_prompt(self,time: datetime.datetime):
- now_time = time.strftime("%H:%M")
- if self.today_done_list:
- previous_doing = self.get_current_num_task(10, True)
- print(previous_doing)
- else:
- previous_doing = "我没做什么事情"
-
-
- prompt = f"我是{self.name},{self.personality},{self.behavior}"
- prompt += f"我今天的日程是:{self.today_schedule_text}\n"
- prompt += f"我之前做了的事情是:{previous_doing},从之前到现在已经过去了{self.schedule_doing_update_interval/60}分钟了\n"
- prompt += f"现在是{now_time},结合我的个人特点和行为习惯,"
- prompt += "推测我现在做什么,具体一些,详细一些\n"
- prompt += "直接返回我在做的事情,不要输出其他内容:"
- return prompt
-
- async def generate_daily_schedule(
- self, target_date: datetime.datetime = None,) -> Dict[str, str]:
- daytime_prompt = self.construct_daytime_prompt(target_date)
- daytime_response,_ = await self.llm_scheduler.generate_response_async(daytime_prompt)
- return daytime_response
-
- def _time_diff(self, time1: str, time2: str) -> int:
- """计算两个时间字符串之间的分钟差"""
- if time1 == "24:00":
- time1 = "23:59"
- if time2 == "24:00":
- time2 = "23:59"
- t1 = datetime.datetime.strptime(time1, "%H:%M")
- t2 = datetime.datetime.strptime(time2, "%H:%M")
- diff = int((t2 - t1).total_seconds() / 60)
- # 考虑时间的循环性
- if diff < -720:
- diff += 1440 # 加一天的分钟
- elif diff > 720:
- diff -= 1440 # 减一天的分钟
- # print(f"时间1[{time1}]: 时间2[{time2}],差值[{diff}]分钟")
- return diff
-
- def print_schedule(self):
- """打印完整的日程安排"""
- if not self.today_schedule_text:
- logger.warning("今日日程有误,将在下次运行时重新生成")
- db.schedule.delete_one({"date": datetime.datetime.now().strftime("%Y-%m-%d")})
- else:
- logger.info("=== 今日日程安排 ===")
- logger.info(self.today_schedule_text)
- logger.info("==================")
- self.enable_output = False
-
- async def update_today_done_list(self):
- # 更新数据库中的 today_done_list
- today_str = datetime.datetime.now().strftime("%Y-%m-%d")
- existing_schedule = db.schedule.find_one({"date": today_str})
-
- if existing_schedule:
- # 更新数据库中的 today_done_list
- db.schedule.update_one(
- {"date": today_str},
- {"$set": {"today_done_list": self.today_done_list}}
- )
- logger.debug(f"已更新{today_str}的已完成活动列表")
- else:
- logger.warning(f"未找到{today_str}的日程记录")
-
- async def move_doing(self):
- current_time = datetime.datetime.now()
- time_str = current_time.strftime("%H:%M")
- doing_prompt = self.construct_doing_prompt(current_time)
- doing_response,_ = await self.llm_scheduler.generate_response_async(doing_prompt)
- self.today_done_list.append((current_time, time_str + "时," + doing_response))
-
- await self.update_today_done_list()
-
- return doing_response
-
- async def get_task_from_time_to_time(self, start_time: str, end_time: str):
- """获取指定时间范围内的任务列表
-
- Args:
- start_time (str): 开始时间,格式为"HH:MM"
- end_time (str): 结束时间,格式为"HH:MM"
-
- Returns:
- list: 时间范围内的任务列表
- """
- result = []
- for task in self.today_done_list:
- task_time = task[0] # 获取任务的时间戳
- task_time_str = task_time.strftime("%H:%M")
-
- # 检查任务时间是否在指定范围内
- if self._time_diff(start_time, task_time_str) >= 0 and self._time_diff(task_time_str, end_time) >= 0:
- result.append(task)
-
- return result
-
- def get_current_num_task(self, num=1, time_info = False):
- """获取最新加入的指定数量的日程
-
- Args:
- num (int): 需要获取的日程数量,默认为1
-
- Returns:
- list: 最新加入的日程列表
- """
- if not self.today_done_list:
- return []
-
- # 确保num不超过列表长度
- num = min(num, len(self.today_done_list))
- pre_doing = ""
- for doing in self.today_done_list[-num:]:
- pre_doing += doing[1]
-
- # 返回最新的num条日程
- return pre_doing
-
- def save_today_schedule_to_db(self):
- """保存日程到数据库,同时初始化 today_done_list"""
- date_str = datetime.datetime.now().strftime("%Y-%m-%d")
- schedule_data = {
- "date": date_str,
- "schedule": self.today_schedule_text,
- "today_done_list": self.today_done_list if hasattr(self, 'today_done_list') else []
- }
- # 使用 upsert 操作,如果存在则更新,不存在则插入
- db.schedule.update_one(
- {"date": date_str},
- {"$set": schedule_data},
- upsert=True
- )
- logger.debug(f"已保存{date_str}的日程到数据库")
-
- def load_schedule_from_db(self, date: datetime.datetime):
- """从数据库加载日程,同时加载 today_done_list"""
- date_str = date.strftime("%Y-%m-%d")
- existing_schedule = db.schedule.find_one({"date": date_str})
-
- if existing_schedule:
- schedule_text = existing_schedule["schedule"]
- return schedule_text, existing_schedule.get("today_done_list", [])
- else:
- logger.debug(f"{date_str}的日程不存在")
- return None, None
-
-async def main():
- # 使用示例
- scheduler = ScheduleGenerator(name="麦麦", personality="你叫麦麦,你19岁,是一个大二的女大学生,你有一头黑色短发,你会刷贴吧,你现在在学习心理学", behavior="你比较内向,一般熬夜比较晚,然后第二天早上10点起床吃早午饭")
- await scheduler.mai_schedule_start()
-
-
-
-# 当作为组件导入时使用的实例
-bot_schedule = ScheduleGenerator()
-
-if __name__ == "__main__":
- import asyncio
- # 当直接运行此文件时执行
- asyncio.run(main())
diff --git a/src/think_flow_demo/current_mind.py b/src/think_flow_demo/current_mind.py
index 6facdbf9..cce93dc7 100644
--- a/src/think_flow_demo/current_mind.py
+++ b/src/think_flow_demo/current_mind.py
@@ -5,6 +5,8 @@ from src.plugins.models.utils_model import LLM_request
from src.plugins.chat.config import global_config
import re
import time
+from src.plugins.schedule.schedule_generator import bot_schedule
+
class CuttentState:
def __init__(self):
self.willing = 0
@@ -57,10 +59,12 @@ class SubHeartflow:
personality_info = open("src/think_flow_demo/personality_info.txt", "r", encoding="utf-8").read()
current_thinking_info = self.current_mind
mood_info = self.current_state.mood
- related_memory_info = 'memory'
+ related_memory_info = ''
message_stream_info = self.outer_world.talking_summary
+ schedule_info = bot_schedule.get_current_num_task(num = 2,time_info = False)
prompt = ""
+ prompt += f"你刚刚在做的事情是:{schedule_info}\n"
# prompt += f"麦麦的总体想法是:{self.main_heartflow_info}\n\n"
prompt += f"{personality_info}\n"
prompt += f"现在你正在上网,和qq群里的网友们聊天,群里正在聊的话题是:{message_stream_info}\n"
diff --git a/src/think_flow_demo/heartflow.py b/src/think_flow_demo/heartflow.py
index 45843e49..a0a2d4c1 100644
--- a/src/think_flow_demo/heartflow.py
+++ b/src/think_flow_demo/heartflow.py
@@ -2,6 +2,7 @@ from .current_mind import SubHeartflow
from src.plugins.moods.moods import MoodManager
from src.plugins.models.utils_model import LLM_request
from src.plugins.chat.config import global_config
+from src.plugins.schedule.schedule_generator import bot_schedule
import asyncio
class CuttentState:
@@ -30,8 +31,8 @@ class Heartflow:
async def heartflow_start_working(self):
while True:
- # await self.do_a_thinking()
- await asyncio.sleep(60)
+ await self.do_a_thinking()
+ await asyncio.sleep(900)
async def do_a_thinking(self):
print("麦麦大脑袋转起来了")
@@ -43,9 +44,11 @@ class Heartflow:
related_memory_info = 'memory'
sub_flows_info = await self.get_all_subheartflows_minds()
+ schedule_info = bot_schedule.get_current_num_task(num = 5,time_info = True)
+
prompt = ""
+ prompt += f"你刚刚在做的事情是:{schedule_info}\n"
prompt += f"{personality_info}\n"
- # prompt += f"现在你正在上网,和qq群里的网友们聊天,群里正在聊的话题是:{message_stream_info}\n"
prompt += f"你想起来{related_memory_info}。"
prompt += f"刚刚你的主要想法是{current_thinking_info}。"
prompt += f"你还有一些小想法,因为你在参加不同的群聊天,是你正在做的事情:{sub_flows_info}\n"
diff --git a/template/bot_config_template.toml b/template/bot_config_template.toml
index 6591d427..668b40b8 100644
--- a/template/bot_config_template.toml
+++ b/template/bot_config_template.toml
@@ -43,6 +43,7 @@ personality_3_probability = 0.1 # 第三种人格出现概率,请确保三个
[schedule]
enable_schedule_gen = true # 是否启用日程表(尚未完成)
prompt_schedule_gen = "用几句话描述描述性格特点或行动规律,这个特征会用来生成日程表"
+schedule_doing_update_interval = 900 # 日程表更新间隔 单位秒
[message]
max_context_size = 15 # 麦麦获得的上文数量,建议15,太短太长都会导致脑袋尖尖
From 67291f1b4906b399f7acc22fe7c0387557b0688b Mon Sep 17 00:00:00 2001
From: SengokuCola <1026294844@qq.com>
Date: Wed, 26 Mar 2025 23:19:19 +0800
Subject: [PATCH 03/11] =?UTF-8?q?better:=E4=B8=8D=E5=A5=BD=E6=84=8F?=
=?UTF-8?q?=E6=80=9D=E5=88=9A=E5=88=9A=E4=B8=8D=E8=A1=8C=EF=BC=8C=E7=8E=B0?=
=?UTF-8?q?=E5=9C=A8=E5=8F=AF=E4=BB=A5=E4=BA=86?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/common/logger.py | 18 ++++++++++++++++++
src/plugins/schedule/schedule_generator.py | 14 +++++++++++---
src/think_flow_demo/heartflow.py | 17 ++++++++++++++---
3 files changed, 43 insertions(+), 6 deletions(-)
diff --git a/src/common/logger.py b/src/common/logger.py
index b910427b..8a9d0892 100644
--- a/src/common/logger.py
+++ b/src/common/logger.py
@@ -122,6 +122,23 @@ SENDER_STYLE_CONFIG = {
},
}
+HEARTFLOW_STYLE_CONFIG = {
+ "advanced": {
+ "console_format": (
+ "{time:YYYY-MM-DD HH:mm:ss} | "
+ "{level: <8} | "
+ "{extra[module]: <12} | "
+ "麦麦大脑袋 | "
+ "{message}"
+ ),
+ "file_format": ("{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 麦麦大脑袋 | {message}"),
+ },
+ "simple": {
+ "console_format": ("{time:MM-DD HH:mm} | 麦麦大脑袋 | {message}"), # noqa: E501
+ "file_format": ("{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 麦麦大脑袋 | {message}"),
+ },
+}
+
SCHEDULE_STYLE_CONFIG = {
"advanced": {
"console_format": (
@@ -201,6 +218,7 @@ LLM_STYLE_CONFIG = LLM_STYLE_CONFIG["simple"] if SIMPLE_OUTPUT else LLM_STYLE_CO
CHAT_STYLE_CONFIG = CHAT_STYLE_CONFIG["simple"] if SIMPLE_OUTPUT else CHAT_STYLE_CONFIG["advanced"]
MOOD_STYLE_CONFIG = MOOD_STYLE_CONFIG["simple"] if SIMPLE_OUTPUT else MOOD_STYLE_CONFIG["advanced"]
SCHEDULE_STYLE_CONFIG = SCHEDULE_STYLE_CONFIG["simple"] if SIMPLE_OUTPUT else SCHEDULE_STYLE_CONFIG["advanced"]
+HEARTFLOW_STYLE_CONFIG = HEARTFLOW_STYLE_CONFIG["simple"] if SIMPLE_OUTPUT else HEARTFLOW_STYLE_CONFIG["advanced"]
def is_registered_module(record: dict) -> bool:
"""检查是否为已注册的模块"""
diff --git a/src/plugins/schedule/schedule_generator.py b/src/plugins/schedule/schedule_generator.py
index d39b0517..a02a2235 100644
--- a/src/plugins/schedule/schedule_generator.py
+++ b/src/plugins/schedule/schedule_generator.py
@@ -76,8 +76,9 @@ class ScheduleGenerator:
self.print_schedule()
# 执行当前活动
- current_activity = await self.move_doing(mind_thinking="")
- logger.info(f"当前活动: {current_activity}")
+ # mind_thinking = subheartflow_manager.current_state.current_mind
+
+ await self.move_doing()
await asyncio.sleep(self.schedule_doing_update_interval)
@@ -190,12 +191,19 @@ class ScheduleGenerator:
async def move_doing(self,mind_thinking: str = ""):
current_time = datetime.datetime.now()
- doing_prompt = self.construct_doing_prompt(current_time,mind_thinking)
+ if mind_thinking:
+ doing_prompt = self.construct_doing_prompt(current_time,mind_thinking)
+ else:
+ doing_prompt = self.construct_doing_prompt(current_time)
+
+ print(doing_prompt)
doing_response,_ = await self.llm_scheduler_doing.generate_response_async(doing_prompt)
self.today_done_list.append((current_time,doing_response))
await self.update_today_done_list()
+ logger.info(f"当前活动: {doing_response}")
+
return doing_response
async def get_task_from_time_to_time(self, start_time: str, end_time: str):
diff --git a/src/think_flow_demo/heartflow.py b/src/think_flow_demo/heartflow.py
index a0a2d4c1..b80bb088 100644
--- a/src/think_flow_demo/heartflow.py
+++ b/src/think_flow_demo/heartflow.py
@@ -4,6 +4,14 @@ from src.plugins.models.utils_model import LLM_request
from src.plugins.chat.config import global_config
from src.plugins.schedule.schedule_generator import bot_schedule
import asyncio
+from src.common.logger import get_module_logger, LogConfig, HEARTFLOW_STYLE_CONFIG # noqa: E402
+
+heartflow_config = LogConfig(
+ # 使用海马体专用样式
+ console_format=HEARTFLOW_STYLE_CONFIG["console_format"],
+ file_format=HEARTFLOW_STYLE_CONFIG["file_format"],
+)
+logger = get_module_logger("heartflow", config=heartflow_config)
class CuttentState:
def __init__(self):
@@ -32,10 +40,10 @@ class Heartflow:
async def heartflow_start_working(self):
while True:
await self.do_a_thinking()
- await asyncio.sleep(900)
+ await asyncio.sleep(100)
async def do_a_thinking(self):
- print("麦麦大脑袋转起来了")
+ logger.info("麦麦大脑袋转起来了")
self.current_state.update_current_state_info()
personality_info = open("src/think_flow_demo/personality_info.txt", "r", encoding="utf-8").read()
@@ -61,7 +69,10 @@ class Heartflow:
self.update_current_mind(reponse)
self.current_mind = reponse
- print(f"麦麦的总体脑内状态:{self.current_mind}")
+ logger.info(f"麦麦的总体脑内状态:{self.current_mind}")
+ logger.info("麦麦想了想,当前活动:")
+ await bot_schedule.move_doing(self.current_mind)
+
for _, subheartflow in self._subheartflows.items():
subheartflow.main_heartflow_info = reponse
From 805bde06462f19c57003739efc71e7886508b856 Mon Sep 17 00:00:00 2001
From: SengokuCola <1026294844@qq.com>
Date: Wed, 26 Mar 2025 23:26:32 +0800
Subject: [PATCH 04/11] Update schedule_generator.py
---
src/plugins/schedule/schedule_generator.py | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/plugins/schedule/schedule_generator.py b/src/plugins/schedule/schedule_generator.py
index a02a2235..f2bce21c 100644
--- a/src/plugins/schedule/schedule_generator.py
+++ b/src/plugins/schedule/schedule_generator.py
@@ -117,14 +117,14 @@ class ScheduleGenerator:
prompt = f"你是{self.name},{self.personality},{self.behavior}"
prompt += f"你昨天的日程是:{self.yesterday_schedule_text}\n"
prompt += f"请为你生成{date_str}({weekday})的日程安排,结合你的个人特点和行为习惯\n"
- prompt += "推测你的日程安排,包括你一天都在做什么,有什么发现和思考,具体一些,详细一些,需要1500字以上,精确到每半个小时,记得写明时间\n"
- prompt += "直接返回你的日程,不要输出其他内容:"
+ prompt += "推测你的日程安排,包括你一天都在做什么,从起床到睡眠,有什么发现和思考,具体一些,详细一些,需要1500字以上,精确到每半个小时,记得写明时间\n"
+ prompt += "直接返回你的日程,从起床到睡觉,不要输出其他内容:"
return prompt
def construct_doing_prompt(self,time: datetime.datetime,mind_thinking: str = ""):
now_time = time.strftime("%H:%M")
if self.today_done_list:
- previous_doings = self.get_current_num_task(10, True)
+ previous_doings = self.get_current_num_task(5, True)
# print(previous_doings)
else:
previous_doings = "你没做什么事情"
@@ -132,9 +132,9 @@ class ScheduleGenerator:
prompt = f"你是{self.name},{self.personality},{self.behavior}"
prompt += f"你今天的日程是:{self.today_schedule_text}\n"
+ prompt += f"你之前做了的事情是:{previous_doings},从之前到现在已经过去了{self.schedule_doing_update_interval/60}分钟了\n"
if mind_thinking:
prompt += f"你脑子里在想:{mind_thinking}\n"
- prompt += f"你之前做了的事情是:{previous_doings},从之前到现在已经过去了{self.schedule_doing_update_interval/60}分钟了\n"
prompt += f"现在是{now_time},结合你的个人特点和行为习惯,"
prompt += "推测你现在做什么,具体一些,详细一些\n"
prompt += "直接返回你在做的事情,不要输出其他内容:"
@@ -196,7 +196,7 @@ class ScheduleGenerator:
else:
doing_prompt = self.construct_doing_prompt(current_time)
- print(doing_prompt)
+ # print(doing_prompt)
doing_response,_ = await self.llm_scheduler_doing.generate_response_async(doing_prompt)
self.today_done_list.append((current_time,doing_response))
From def7ee7ace9e3030e0cbc3c67d7edee529f3e3fd Mon Sep 17 00:00:00 2001
From: SengokuCola <1026294844@qq.com>
Date: Wed, 26 Mar 2025 23:38:37 +0800
Subject: [PATCH 05/11] Update message_sender.py
---
src/plugins/chat/message_sender.py | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/src/plugins/chat/message_sender.py b/src/plugins/chat/message_sender.py
index 8a9b4446..7528a2e5 100644
--- a/src/plugins/chat/message_sender.py
+++ b/src/plugins/chat/message_sender.py
@@ -61,6 +61,7 @@ class Message_Sender:
if not is_recalled:
typing_time = calculate_typing_time(message.processed_plain_text)
+ logger.info(f"麦麦正在打字,预计需要{typing_time}秒")
await asyncio.sleep(typing_time)
message_json = message.to_dict()
@@ -99,7 +100,7 @@ class MessageContainer:
self.max_size = max_size
self.messages = []
self.last_send_time = 0
- self.thinking_timeout = 20 # 思考超时时间(秒)
+ self.thinking_timeout = 10 # 思考超时时间(秒)
def get_timeout_messages(self) -> List[MessageSending]:
"""获取所有超时的Message_Sending对象(思考时间超过30秒),按thinking_start_time排序"""
@@ -208,7 +209,7 @@ class MessageManager:
# print(thinking_time)
if (
message_earliest.is_head
- and message_earliest.update_thinking_time() > 15
+ and message_earliest.update_thinking_time() > 20
and not message_earliest.is_private_message() # 避免在私聊时插入reply
):
logger.debug(f"设置回复消息{message_earliest.processed_plain_text}")
@@ -235,7 +236,7 @@ class MessageManager:
# print(msg.is_private_message())
if (
msg.is_head
- and msg.update_thinking_time() > 15
+ and msg.update_thinking_time() > 25
and not msg.is_private_message() # 避免在私聊时插入reply
):
logger.debug(f"设置回复消息{msg.processed_plain_text}")
From 5886b1c849c8080ac29d14ef739cb1ee65e2f3fc Mon Sep 17 00:00:00 2001
From: SengokuCola <1026294844@qq.com>
Date: Thu, 27 Mar 2025 00:10:21 +0800
Subject: [PATCH 06/11] =?UTF-8?q?fix=20=E4=BF=AE=E5=A4=8D=E4=BA=86?=
=?UTF-8?q?=E7=82=B9=E5=B0=8Fbug?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/plugins/schedule/schedule_generator.py | 4 +--
src/plugins/utils/statistic.py | 37 +++++++++++++++++++---
src/think_flow_demo/current_mind.py | 4 +--
3 files changed, 36 insertions(+), 9 deletions(-)
diff --git a/src/plugins/schedule/schedule_generator.py b/src/plugins/schedule/schedule_generator.py
index f2bce21c..b14ebd1b 100644
--- a/src/plugins/schedule/schedule_generator.py
+++ b/src/plugins/schedule/schedule_generator.py
@@ -27,7 +27,7 @@ class ScheduleGenerator:
def __init__(self, ):
# 使用离线LLM模型
self.llm_scheduler_all = LLM_request(
- model= global_config.llm_reasoning, temperature=0.9, max_tokens=2048,request_type="schedule")
+ model= global_config.llm_reasoning, temperature=0.9, max_tokens=7000,request_type="schedule")
self.llm_scheduler_doing = LLM_request(
model= global_config.llm_normal, temperature=0.9, max_tokens=2048,request_type="schedule")
@@ -43,7 +43,7 @@ class ScheduleGenerator:
self.start_time = datetime.datetime.now()
- self.schedule_doing_update_interval = 60 #最好大于60
+ self.schedule_doing_update_interval = 300 #最好大于60
def initialize(self,name: str = "bot_name", personality: str = "你是一个爱国爱党的新时代青年", behavior: str = "你非常外向,喜欢尝试新事物和人交流",interval: int = 60):
"""初始化日程系统"""
diff --git a/src/plugins/utils/statistic.py b/src/plugins/utils/statistic.py
index f03067cb..aad33e88 100644
--- a/src/plugins/utils/statistic.py
+++ b/src/plugins/utils/statistic.py
@@ -20,6 +20,13 @@ class LLMStatistics:
self.output_file = output_file
self.running = False
self.stats_thread = None
+ self._init_database()
+
+ def _init_database(self):
+ """初始化数据库集合"""
+ if "online_time" not in db.list_collection_names():
+ db.create_collection("online_time")
+ db.online_time.create_index([("timestamp", 1)])
def start(self):
"""启动统计线程"""
@@ -35,6 +42,16 @@ class LLMStatistics:
if self.stats_thread:
self.stats_thread.join()
+ def _record_online_time(self):
+ """记录在线时间"""
+ try:
+ db.online_time.insert_one({
+ "timestamp": datetime.now(),
+ "duration": 5 # 5分钟
+ })
+ except Exception:
+ logger.exception("记录在线时间失败")
+
def _collect_statistics_for_period(self, start_time: datetime) -> Dict[str, Any]:
"""收集指定时间段的LLM请求统计数据
@@ -56,10 +73,11 @@ class LLMStatistics:
"tokens_by_type": defaultdict(int),
"tokens_by_user": defaultdict(int),
"tokens_by_model": defaultdict(int),
+ # 新增在线时间统计
+ "online_time_minutes": 0,
}
cursor = db.llm_usage.find({"timestamp": {"$gte": start_time}})
-
total_requests = 0
for doc in cursor:
@@ -74,7 +92,7 @@ class LLMStatistics:
prompt_tokens = doc.get("prompt_tokens", 0)
completion_tokens = doc.get("completion_tokens", 0)
- total_tokens = prompt_tokens + completion_tokens # 根据数据库字段调整
+ total_tokens = prompt_tokens + completion_tokens
stats["tokens_by_type"][request_type] += total_tokens
stats["tokens_by_user"][user_id] += total_tokens
stats["tokens_by_model"][model_name] += total_tokens
@@ -91,6 +109,11 @@ class LLMStatistics:
if total_requests > 0:
stats["average_tokens"] = stats["total_tokens"] / total_requests
+ # 统计在线时间
+ online_time_cursor = db.online_time.find({"timestamp": {"$gte": start_time}})
+ for doc in online_time_cursor:
+ stats["online_time_minutes"] += doc.get("duration", 0)
+
return stats
def _collect_all_statistics(self) -> Dict[str, Dict[str, Any]]:
@@ -115,7 +138,8 @@ class LLMStatistics:
output.append(f"总请求数: {stats['total_requests']}")
if stats["total_requests"] > 0:
output.append(f"总Token数: {stats['total_tokens']}")
- output.append(f"总花费: {stats['total_cost']:.4f}¥\n")
+ output.append(f"总花费: {stats['total_cost']:.4f}¥")
+ output.append(f"在线时间: {stats['online_time_minutes']}分钟\n")
data_fmt = "{:<32} {:>10} {:>14} {:>13.4f} ¥"
@@ -184,13 +208,16 @@ class LLMStatistics:
"""统计循环,每1分钟运行一次"""
while self.running:
try:
+ # 记录在线时间
+ self._record_online_time()
+ # 收集并保存统计数据
all_stats = self._collect_all_statistics()
self._save_statistics(all_stats)
except Exception:
logger.exception("统计数据处理失败")
- # 等待1分钟
- for _ in range(60):
+ # 等待5分钟
+ for _ in range(300): # 5分钟 = 300秒
if not self.running:
break
time.sleep(1)
diff --git a/src/think_flow_demo/current_mind.py b/src/think_flow_demo/current_mind.py
index cce93dc7..f15b036c 100644
--- a/src/think_flow_demo/current_mind.py
+++ b/src/think_flow_demo/current_mind.py
@@ -46,11 +46,11 @@ class SubHeartflow:
current_time = time.time()
if current_time - self.last_reply_time > 180: # 3分钟 = 180秒
# print(f"{self.observe_chat_id}麦麦已经3分钟没有回复了,暂时停止思考")
- await asyncio.sleep(25) # 每30秒检查一次
+ await asyncio.sleep(60) # 每30秒检查一次
else:
await self.do_a_thinking()
await self.judge_willing()
- await asyncio.sleep(25)
+ await asyncio.sleep(60)
async def do_a_thinking(self):
print("麦麦小脑袋转起来了")
From 8da4729c175bbe4ff5fe35ba9de63d68b142b9a6 Mon Sep 17 00:00:00 2001
From: SengokuCola <1026294844@qq.com>
Date: Thu, 27 Mar 2025 00:23:13 +0800
Subject: [PATCH 07/11] fix ruff
---
src/plugins/chat/__init__.py | 6 ++-
src/plugins/chat/prompt_builder.py | 2 +-
src/plugins/schedule/offline_llm.py | 3 --
src/plugins/schedule/schedule_generator.py | 18 ++++++---
配置文件错误排查.py | 44 +++++++++++++++-------
5 files changed, 49 insertions(+), 24 deletions(-)
diff --git a/src/plugins/chat/__init__.py b/src/plugins/chat/__init__.py
index 8bbb16bf..55b83e88 100644
--- a/src/plugins/chat/__init__.py
+++ b/src/plugins/chat/__init__.py
@@ -84,7 +84,11 @@ async def start_background_tasks():
@driver.on_startup
async def init_schedule():
"""在 NoneBot2 启动时初始化日程系统"""
- bot_schedule.initialize(name=global_config.BOT_NICKNAME, personality=global_config.PROMPT_PERSONALITY, behavior=global_config.PROMPT_SCHEDULE_GEN, interval=global_config.SCHEDULE_DOING_UPDATE_INTERVAL)
+ bot_schedule.initialize(
+ name=global_config.BOT_NICKNAME,
+ personality=global_config.PROMPT_PERSONALITY,
+ behavior=global_config.PROMPT_SCHEDULE_GEN,
+ interval=global_config.SCHEDULE_DOING_UPDATE_INTERVAL)
asyncio.create_task(bot_schedule.mai_schedule_start())
@driver.on_startup
diff --git a/src/plugins/chat/prompt_builder.py b/src/plugins/chat/prompt_builder.py
index 283ea0ea..dc2e5930 100644
--- a/src/plugins/chat/prompt_builder.py
+++ b/src/plugins/chat/prompt_builder.py
@@ -57,7 +57,7 @@ class PromptBuilder:
mood_prompt = mood_manager.get_prompt()
# 日程构建
- schedule_prompt = f'''你现在正在做的事情是:{bot_schedule.get_current_num_task(num = 1,time_info = False)}'''
+ # schedule_prompt = f'''你现在正在做的事情是:{bot_schedule.get_current_num_task(num = 1,time_info = False)}'''
# 获取聊天上下文
chat_in_group = True
diff --git a/src/plugins/schedule/offline_llm.py b/src/plugins/schedule/offline_llm.py
index f274740f..5276f380 100644
--- a/src/plugins/schedule/offline_llm.py
+++ b/src/plugins/schedule/offline_llm.py
@@ -1,10 +1,7 @@
import asyncio
import os
-import time
-from typing import Tuple, Union
import aiohttp
-import requests
from src.common.logger import get_module_logger
logger = get_module_logger("offline_llm")
diff --git a/src/plugins/schedule/schedule_generator.py b/src/plugins/schedule/schedule_generator.py
index b14ebd1b..41cf187e 100644
--- a/src/plugins/schedule/schedule_generator.py
+++ b/src/plugins/schedule/schedule_generator.py
@@ -24,7 +24,7 @@ logger = get_module_logger("scheduler", config=schedule_config)
class ScheduleGenerator:
# enable_output: bool = True
- def __init__(self, ):
+ def __init__(self):
# 使用离线LLM模型
self.llm_scheduler_all = LLM_request(
model= global_config.llm_reasoning, temperature=0.9, max_tokens=7000,request_type="schedule")
@@ -45,7 +45,11 @@ class ScheduleGenerator:
self.schedule_doing_update_interval = 300 #最好大于60
- def initialize(self,name: str = "bot_name", personality: str = "你是一个爱国爱党的新时代青年", behavior: str = "你非常外向,喜欢尝试新事物和人交流",interval: int = 60):
+ def initialize(
+ self,name: str = "bot_name",
+ personality: str = "你是一个爱国爱党的新时代青年",
+ behavior: str = "你非常外向,喜欢尝试新事物和人交流",
+ interval: int = 60):
"""初始化日程系统"""
self.name = name
self.behavior = behavior
@@ -117,7 +121,7 @@ class ScheduleGenerator:
prompt = f"你是{self.name},{self.personality},{self.behavior}"
prompt += f"你昨天的日程是:{self.yesterday_schedule_text}\n"
prompt += f"请为你生成{date_str}({weekday})的日程安排,结合你的个人特点和行为习惯\n"
- prompt += "推测你的日程安排,包括你一天都在做什么,从起床到睡眠,有什么发现和思考,具体一些,详细一些,需要1500字以上,精确到每半个小时,记得写明时间\n"
+ prompt += "推测你的日程安排,包括你一天都在做什么,从起床到睡眠,有什么发现和思考,具体一些,详细一些,需要1500字以上,精确到每半个小时,记得写明时间\n" #noqa: E501
prompt += "直接返回你的日程,从起床到睡觉,不要输出其他内容:"
return prompt
@@ -132,7 +136,7 @@ class ScheduleGenerator:
prompt = f"你是{self.name},{self.personality},{self.behavior}"
prompt += f"你今天的日程是:{self.today_schedule_text}\n"
- prompt += f"你之前做了的事情是:{previous_doings},从之前到现在已经过去了{self.schedule_doing_update_interval/60}分钟了\n"
+ prompt += f"你之前做了的事情是:{previous_doings},从之前到现在已经过去了{self.schedule_doing_update_interval/60}分钟了\n" #noqa: E501
if mind_thinking:
prompt += f"你脑子里在想:{mind_thinking}\n"
prompt += f"现在是{now_time},结合你的个人特点和行为习惯,"
@@ -284,7 +288,11 @@ class ScheduleGenerator:
async def main():
# 使用示例
scheduler = ScheduleGenerator()
- scheduler.initialize(name="麦麦", personality="你叫麦麦,你19岁,是一个大二的女大学生,你有一头黑色短发,你会刷贴吧,你现在在学习心理学", behavior="你比较内向,一般熬夜比较晚,然后第二天早上10点起床吃早午饭",interval=60)
+ scheduler.initialize(
+ name="麦麦",
+ personality="你叫麦麦,你19岁,是一个大二的女大学生,你有一头黑色短发,你会刷贴吧,你现在在学习心理学",
+ behavior="你比较内向,一般熬夜比较晚,然后第二天早上10点起床吃早午饭",
+ interval=60)
await scheduler.mai_schedule_start()
diff --git a/配置文件错误排查.py b/配置文件错误排查.py
index 11417113..d277ceb4 100644
--- a/配置文件错误排查.py
+++ b/配置文件错误排查.py
@@ -1,8 +1,7 @@
import tomli
import sys
-import re
from pathlib import Path
-from typing import Dict, Any, List, Set, Tuple
+from typing import Dict, Any, List, Tuple
def load_toml_file(file_path: str) -> Dict[str, Any]:
"""加载TOML文件"""
@@ -184,10 +183,15 @@ def check_model_configurations(config: Dict[str, Any], env_vars: Dict[str, str])
provider = model_config["provider"].upper()
# 检查拼写错误
- for known_provider, correct_provider in reverse_mapping.items():
+ for known_provider, _correct_provider in reverse_mapping.items():
# 使用模糊匹配检测拼写错误
- if provider != known_provider and _similar_strings(provider, known_provider) and provider not in reverse_mapping:
- errors.append(f"[model.{model_name}]的provider '{model_config['provider']}' 可能拼写错误,应为 '{known_provider}'")
+ if (provider != known_provider and
+ _similar_strings(provider, known_provider) and
+ provider not in reverse_mapping):
+ errors.append(
+ f"[model.{model_name}]的provider '{model_config['provider']}' "
+ f"可能拼写错误,应为 '{known_provider}'"
+ )
break
return errors
@@ -223,7 +227,7 @@ def check_api_providers(config: Dict[str, Any], env_vars: Dict[str, str]) -> Lis
# 检查配置文件中使用的所有提供商
used_providers = set()
- for model_category, model_config in config["model"].items():
+ for _model_category, model_config in config["model"].items():
if "provider" in model_config:
provider = model_config["provider"]
used_providers.add(provider)
@@ -247,7 +251,7 @@ def check_api_providers(config: Dict[str, Any], env_vars: Dict[str, str]) -> Lis
# 特别检查常见的拼写错误
for provider in used_providers:
if provider.upper() == "SILICONFOLW":
- errors.append(f"提供商 'SILICONFOLW' 存在拼写错误,应为 'SILICONFLOW'")
+ errors.append("提供商 'SILICONFOLW' 存在拼写错误,应为 'SILICONFLOW'")
return errors
@@ -272,7 +276,7 @@ def check_groups_configuration(config: Dict[str, Any]) -> List[str]:
"main": "groups.talk_allowed中存在默认示例值'123',请修改为真实的群号",
"details": [
f" 当前值: {groups['talk_allowed']}",
- f" '123'为示例值,需要替换为真实群号"
+ " '123'为示例值,需要替换为真实群号"
]
})
@@ -371,7 +375,8 @@ def check_memory_config(config: Dict[str, Any]) -> List[str]:
if "memory_compress_rate" in memory and (memory["memory_compress_rate"] <= 0 or memory["memory_compress_rate"] > 1):
errors.append(f"memory.memory_compress_rate值无效: {memory['memory_compress_rate']}, 应在0-1之间")
- if "memory_forget_percentage" in memory and (memory["memory_forget_percentage"] <= 0 or memory["memory_forget_percentage"] > 1):
+ if ("memory_forget_percentage" in memory
+ and (memory["memory_forget_percentage"] <= 0 or memory["memory_forget_percentage"] > 1)):
errors.append(f"memory.memory_forget_percentage值无效: {memory['memory_forget_percentage']}, 应在0-1之间")
return errors
@@ -393,7 +398,10 @@ def check_personality_config(config: Dict[str, Any]) -> List[str]:
else:
# 检查数组长度
if len(personality["prompt_personality"]) < 1:
- errors.append(f"personality.prompt_personality数组长度不足,当前长度: {len(personality['prompt_personality'])}, 需要至少1项")
+ errors.append(
+ f"personality.prompt_personality至少需要1项,"
+ f"当前长度: {len(personality['prompt_personality'])}"
+ )
else:
# 模板默认值
template_values = [
@@ -452,10 +460,13 @@ def check_bot_config(config: Dict[str, Any]) -> List[str]:
def format_results(all_errors):
"""格式化检查结果"""
- sections_errors, prob_sum_errors, prob_range_errors, model_errors, api_errors, groups_errors, kr_errors, willing_errors, memory_errors, personality_errors, bot_results = all_errors
+ sections_errors, prob_sum_errors, prob_range_errors, model_errors, api_errors, groups_errors, kr_errors, willing_errors, memory_errors, personality_errors, bot_results = all_errors # noqa: E501, F821
bot_errors, bot_infos = bot_results
- if not any([sections_errors, prob_sum_errors, prob_range_errors, model_errors, api_errors, groups_errors, kr_errors, willing_errors, memory_errors, personality_errors, bot_errors]):
+ if not any([
+ sections_errors, prob_sum_errors,
+ prob_range_errors, model_errors, api_errors, groups_errors,
+ kr_errors, willing_errors, memory_errors, personality_errors, bot_errors]):
result = "✅ 配置文件检查通过,未发现问题。"
# 添加机器人信息
@@ -574,7 +585,10 @@ def main():
bot_results = check_bot_config(config)
# 格式化并打印结果
- all_errors = (sections_errors, prob_sum_errors, prob_range_errors, model_errors, api_errors, groups_errors, kr_errors, willing_errors, memory_errors, personality_errors, bot_results)
+ all_errors = (
+ sections_errors, prob_sum_errors,
+ prob_range_errors, model_errors, api_errors, groups_errors,
+ kr_errors, willing_errors, memory_errors, personality_errors, bot_results)
result = format_results(all_errors)
print("📋 机器人配置检查结果:")
print(result)
@@ -586,7 +600,9 @@ def main():
bot_errors, _ = bot_results
# 计算普通错误列表的长度
- for errors in [sections_errors, model_errors, api_errors, groups_errors, kr_errors, willing_errors, memory_errors, bot_errors]:
+ for errors in [
+ sections_errors, model_errors, api_errors,
+ groups_errors, kr_errors, willing_errors, memory_errors, bot_errors]:
total_errors += len(errors)
# 计算元组列表的长度(概率相关错误)
From c53ad9e38cafaee532ac6fc235913d97b8bb78ed Mon Sep 17 00:00:00 2001
From: SengokuCola <1026294844@qq.com>
Date: Thu, 27 Mar 2025 00:27:25 +0800
Subject: [PATCH 08/11] Update heartflow.py
---
src/think_flow_demo/heartflow.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/think_flow_demo/heartflow.py b/src/think_flow_demo/heartflow.py
index b80bb088..1079483d 100644
--- a/src/think_flow_demo/heartflow.py
+++ b/src/think_flow_demo/heartflow.py
@@ -40,7 +40,7 @@ class Heartflow:
async def heartflow_start_working(self):
while True:
await self.do_a_thinking()
- await asyncio.sleep(100)
+ await asyncio.sleep(600)
async def do_a_thinking(self):
logger.info("麦麦大脑袋转起来了")
From f0bf6fe83f9a65880cc251a0312d44b06c660b90 Mon Sep 17 00:00:00 2001
From: FuyukiVila <1642421711@qq.com>
Date: Thu, 27 Mar 2025 01:04:07 +0800
Subject: [PATCH 09/11] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E4=BA=86prompt?=
=?UTF-8?q?=E4=B8=AD=E7=9A=84=E6=98=B5=E7=A7=B0=E5=BC=95=E7=94=A8?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/think_flow_demo/heartflow.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/think_flow_demo/heartflow.py b/src/think_flow_demo/heartflow.py
index 1079483d..a77e8485 100644
--- a/src/think_flow_demo/heartflow.py
+++ b/src/think_flow_demo/heartflow.py
@@ -97,7 +97,7 @@ class Heartflow:
prompt = ""
prompt += f"{personality_info}\n"
prompt += f"现在{global_config.BOT_NICKNAME}的想法是:{self.current_mind}\n"
- prompt += f"现在麦麦在qq群里进行聊天,聊天的话题如下:{minds_str}\n"
+ prompt += f"现在{global_config.BOT_NICKNAME}在qq群里进行聊天,聊天的话题如下:{minds_str}\n"
prompt += f"你现在{mood_info}\n"
prompt += '''现在请你总结这些聊天内容,注意关注聊天内容对原有的想法的影响,输出连贯的内心独白
不要太长,但是记得结合上述的消息,要记得你的人设,关注新内容:'''
From a3811675cbfa28bef42ca2374150643ac838b7a9 Mon Sep 17 00:00:00 2001
From: AL76 <735756072@qq.com>
Date: Thu, 27 Mar 2025 01:50:31 +0800
Subject: [PATCH 10/11] =?UTF-8?q?fix:=20=E5=90=8C=E6=AD=A5=E5=BF=83?=
=?UTF-8?q?=E6=B5=81=E4=B8=8E=E6=9C=AC=E4=BD=93=E4=BD=BF=E7=94=A8=E7=9A=84?=
=?UTF-8?q?prompt=EF=BC=8C=E4=BF=9D=E6=8C=81=E4=BA=BA=E8=AE=BE=E4=B8=80?=
=?UTF-8?q?=E8=87=B4?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/think_flow_demo/current_mind.py | 13 ++++++-------
src/think_flow_demo/personality_info.txt | 2 ++
2 files changed, 8 insertions(+), 7 deletions(-)
diff --git a/src/think_flow_demo/current_mind.py b/src/think_flow_demo/current_mind.py
index f15b036c..32d77ef7 100644
--- a/src/think_flow_demo/current_mind.py
+++ b/src/think_flow_demo/current_mind.py
@@ -2,7 +2,7 @@ from .outer_world import outer_world
import asyncio
from src.plugins.moods.moods import MoodManager
from src.plugins.models.utils_model import LLM_request
-from src.plugins.chat.config import global_config
+from src.plugins.chat.config import global_config, BotConfig
import re
import time
from src.plugins.schedule.schedule_generator import bot_schedule
@@ -36,6 +36,8 @@ class SubHeartflow:
if not self.current_mind:
self.current_mind = "你什么也没想"
+
+ self.personality_info = " ".join(BotConfig.PROMPT_PERSONALITY)
def assign_observe(self,stream_id):
self.outer_world = outer_world.get_world_by_stream_id(stream_id)
@@ -56,7 +58,6 @@ class SubHeartflow:
print("麦麦小脑袋转起来了")
self.current_state.update_current_state_info()
- personality_info = open("src/think_flow_demo/personality_info.txt", "r", encoding="utf-8").read()
current_thinking_info = self.current_mind
mood_info = self.current_state.mood
related_memory_info = ''
@@ -66,7 +67,7 @@ class SubHeartflow:
prompt = ""
prompt += f"你刚刚在做的事情是:{schedule_info}\n"
# prompt += f"麦麦的总体想法是:{self.main_heartflow_info}\n\n"
- prompt += f"{personality_info}\n"
+ prompt += f"{self.personality_info}\n"
prompt += f"现在你正在上网,和qq群里的网友们聊天,群里正在聊的话题是:{message_stream_info}\n"
prompt += f"你想起来{related_memory_info}。"
prompt += f"刚刚你的想法是{current_thinking_info}。"
@@ -84,7 +85,6 @@ class SubHeartflow:
# print("麦麦脑袋转起来了")
self.current_state.update_current_state_info()
- personality_info = open("src/think_flow_demo/personality_info.txt", "r", encoding="utf-8").read()
current_thinking_info = self.current_mind
mood_info = self.current_state.mood
related_memory_info = 'memory'
@@ -93,7 +93,7 @@ class SubHeartflow:
reply_info = reply_content
prompt = ""
- prompt += f"{personality_info}\n"
+ prompt += f"{self.personality_info}\n"
prompt += f"现在你正在上网,和qq群里的网友们聊天,群里正在聊的话题是:{message_stream_info}\n"
prompt += f"你想起来{related_memory_info}。"
prompt += f"刚刚你的想法是{current_thinking_info}。"
@@ -114,12 +114,11 @@ class SubHeartflow:
async def judge_willing(self):
# print("麦麦闹情绪了1")
- personality_info = open("src/think_flow_demo/personality_info.txt", "r", encoding="utf-8").read()
current_thinking_info = self.current_mind
mood_info = self.current_state.mood
# print("麦麦闹情绪了2")
prompt = ""
- prompt += f"{personality_info}\n"
+ prompt += f"{self.personality_info}\n"
prompt += "现在你正在上网,和qq群里的网友们聊天"
prompt += f"你现在的想法是{current_thinking_info}。"
prompt += f"你现在{mood_info}。"
diff --git a/src/think_flow_demo/personality_info.txt b/src/think_flow_demo/personality_info.txt
index a9598819..d7b9e4ec 100644
--- a/src/think_flow_demo/personality_info.txt
+++ b/src/think_flow_demo/personality_info.txt
@@ -1 +1,3 @@
+// 为了解决issue-589,已经将心流引用的内容改为了bot_config.toml中的prompt_personality
+// 请移步配置文件进行更改
你叫麦麦,你19岁,是一个大二的女大学生,你有一头黑色短发,你会刷贴吧
\ No newline at end of file
From 3b23be001ea6de73eb39357d08a1d1810f8ac4a1 Mon Sep 17 00:00:00 2001
From: AL76 <735756072@qq.com>
Date: Thu, 27 Mar 2025 02:04:26 +0800
Subject: [PATCH 11/11] =?UTF-8?q?fix:=20=E5=90=8C=E6=AD=A5=E5=BF=83?=
=?UTF-8?q?=E6=B5=81=E4=B8=8E=E6=9C=AC=E4=BD=93=E4=BD=BF=E7=94=A8=E7=9A=84?=
=?UTF-8?q?prompt=EF=BC=8C=E4=BF=9D=E6=8C=81=E4=BA=BA=E8=AE=BE=E4=B8=80?=
=?UTF-8?q?=E8=87=B4=EF=BC=88=E5=88=9A=E5=88=9A=E5=B0=91=E6=94=B9=E4=BA=86?=
=?UTF-8?q?=E4=B8=AA=E6=96=87=E4=BB=B6=EF=BC=89?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/think_flow_demo/heartflow.py | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/think_flow_demo/heartflow.py b/src/think_flow_demo/heartflow.py
index a77e8485..dcdbe508 100644
--- a/src/think_flow_demo/heartflow.py
+++ b/src/think_flow_demo/heartflow.py
@@ -1,7 +1,7 @@
from .current_mind import SubHeartflow
from src.plugins.moods.moods import MoodManager
from src.plugins.models.utils_model import LLM_request
-from src.plugins.chat.config import global_config
+from src.plugins.chat.config import global_config, BotConfig
from src.plugins.schedule.schedule_generator import bot_schedule
import asyncio
from src.common.logger import get_module_logger, LogConfig, HEARTFLOW_STYLE_CONFIG # noqa: E402
@@ -46,7 +46,7 @@ class Heartflow:
logger.info("麦麦大脑袋转起来了")
self.current_state.update_current_state_info()
- personality_info = open("src/think_flow_demo/personality_info.txt", "r", encoding="utf-8").read()
+ personality_info = " ".join(BotConfig.PROMPT_PERSONALITY)
current_thinking_info = self.current_mind
mood_info = self.current_state.mood
related_memory_info = 'memory'
@@ -91,7 +91,7 @@ class Heartflow:
return await self.minds_summary(sub_minds)
async def minds_summary(self,minds_str):
- personality_info = open("src/think_flow_demo/personality_info.txt", "r", encoding="utf-8").read()
+ personality_info = " ".join(BotConfig.PROMPT_PERSONALITY)
mood_info = self.current_state.mood
prompt = ""