From 5f7d82ae29f3586ef189c3401db9ee61ac8c91e9 Mon Sep 17 00:00:00 2001
From: XuChenXu <91937041+ChenXu233@users.noreply.github.com>
Date: Mon, 30 Dec 2024 23:14:49 +0800
Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20=E8=AE=B0=E5=BF=86=E7=B3=BB?=
 =?UTF-8?q?=E7=BB=9F=EF=BC=9A=E5=AE=9A=E6=97=B6=E8=AE=B0=E5=BF=86=E6=95=B4?=
 =?UTF-8?q?=E7=90=86=20(#31)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* :sparkles: 添加记忆系统

* :art: black优化格式

* :bug: 删除apscheduler

* :sparkles: 将记忆插件转换为插件形式

* :bug: 修复函数调用问题

* :sparkles: 记忆系统:定时记忆整理

* :art: pre-commit 检查
---
 nonebot_plugin_marshoai/azure.py              |  2 +-
 .../plugin/func_call/caller.py                |  2 +-
 .../plugins/marshoai_memory/__init__.py       | 51 +++++++++++++++----
 .../plugins/marshoai_memory/config.py         |  9 ++++
 pyproject.toml                                |  3 +-
 5 files changed, 54 insertions(+), 13 deletions(-)
 create mode 100644 nonebot_plugin_marshoai/plugins/marshoai_memory/config.py

diff --git a/nonebot_plugin_marshoai/azure.py b/nonebot_plugin_marshoai/azure.py
index cf380e25..49f27aec 100644
--- a/nonebot_plugin_marshoai/azure.py
+++ b/nonebot_plugin_marshoai/azure.py
@@ -407,7 +407,7 @@ async def marsho(
                             )  # 获取返回值
                         else:
                             if caller := get_function_calls().get(
-                                tool_call.function.name.replace("-", ".")
+                                tool_call.function.name
                             ):
                                 logger.debug(f"调用插件函数 {caller.full_name}")
                                 # 权限检查,规则检查 TODO
diff --git a/nonebot_plugin_marshoai/plugin/func_call/caller.py b/nonebot_plugin_marshoai/plugin/func_call/caller.py
index b04ba987..2f5fbda4 100644
--- a/nonebot_plugin_marshoai/plugin/func_call/caller.py
+++ b/nonebot_plugin_marshoai/plugin/func_call/caller.py
@@ -142,7 +142,7 @@ class Caller:
             module_name = ""
 
         self.module_name = module_name
-        _caller_data[self.full_name] = self
+        _caller_data[self.aifc_name] = self
         logger.opt(colors=True).debug(
             f"<y>加载函数 {self.full_name}: {self._description}</y>"
         )
diff --git a/nonebot_plugin_marshoai/plugins/marshoai_memory/__init__.py b/nonebot_plugin_marshoai/plugins/marshoai_memory/__init__.py
index 5f35252c..d38cf843 100644
--- a/nonebot_plugin_marshoai/plugins/marshoai_memory/__init__.py
+++ b/nonebot_plugin_marshoai/plugins/marshoai_memory/__init__.py
@@ -1,14 +1,19 @@
 import json
 from pathlib import Path
 
-from nonebot import require
-from nonebot_plugin_localstore import get_plugin_data_file  # type: ignore
+from azure.ai.inference.models import UserMessage
+from nonebot import get_driver, logger, require
+from nonebot_plugin_localstore import get_plugin_data_file
 
-from nonebot_plugin_marshoai.plugin import (  # type: ignore
-    PluginMetadata,
-    on_function_call,
-)
-from nonebot_plugin_marshoai.plugin.func_call.params import String  # type: ignore
+require("nonebot_plugin_apscheduler")
+require("nonebot_plugin_marshoai")
+from nonebot_plugin_apscheduler import scheduler
+
+from nonebot_plugin_marshoai.azure import client
+from nonebot_plugin_marshoai.plugin import PluginMetadata, on_function_call
+from nonebot_plugin_marshoai.plugin.func_call.params import String
+
+from .config import plugin_config
 
 __marsho_meta__ = PluginMetadata(
     name="记忆保存",
@@ -21,6 +26,7 @@ if not Path(memory_path).exists():
     with open(memory_path, "w", encoding="utf-8") as f:
         json.dump({}, f, ensure_ascii=False, indent=4)
 # print(memory_path)
+driver = get_driver()
 
 
 @on_function_call(
@@ -45,7 +51,7 @@ async def write_memory(memory: str, user_id: str):
 
 
 @on_function_call(
-    description="当用户与你发起对话时,你需要回忆有关他的一切,因此调用此函数读取记忆内容"
+    description="你需要回忆有关用户的一些知识时,调用此函数读取记忆内容,当用户问问题的时候也尽量调用此函数参考"
 ).params(user_id=String(description="你想读取记忆的人的id"))
 async def read_memory(user_id: str):
     with open(memory_path, "r", encoding="utf-8") as f:
@@ -61,5 +67,30 @@ async def organize_memories():
     with open(memory_path, "r", encoding="utf-8") as f:
         memory_data = json.load(f)
     for i in memory_data:
-        ...
-        # TODO 用大模型对记忆进行整理
+        memory_data_ = "\n".join(memory_data[i])
+        msg = f"这是一些大模型记忆信息,请你保留重要内容,尽量减少无用的记忆后重新输出记忆内容,浓缩为一行:\n{memory_data_}"
+        res = await client.complete(UserMessage(content=msg))
+        try:
+            memory = res.choices[0].message.content  # type: ignore
+            memory_data[i] = memory
+        except AttributeError:
+            logger.error(f"整理关于{i}的记忆时出错:{res}")
+
+    with open(memory_path, "w", encoding="utf-8") as f:
+        json.dump(memory_data, f, ensure_ascii=False, indent=4)
+
+
+if plugin_config.marshoai_plugin_memory_scheduler:
+
+    @driver.on_startup
+    async def _():
+        logger.info("小绵定时记忆整理已启动!")
+        scheduler.add_job(
+            organize_memories,
+            "cron",
+            hour="0",
+            minute="0",
+            second="0",
+            day="*",
+            id="organize_memories",
+        )
diff --git a/nonebot_plugin_marshoai/plugins/marshoai_memory/config.py b/nonebot_plugin_marshoai/plugins/marshoai_memory/config.py
new file mode 100644
index 00000000..c72c6e5c
--- /dev/null
+++ b/nonebot_plugin_marshoai/plugins/marshoai_memory/config.py
@@ -0,0 +1,9 @@
+from nonebot import get_plugin_config, logger
+from pydantic import BaseModel
+
+
+class ConfigModel(BaseModel):
+    marshoai_plugin_memory_scheduler: bool = True
+
+
+plugin_config: ConfigModel = get_plugin_config(ConfigModel)
diff --git a/pyproject.toml b/pyproject.toml
index 5d2f8b71..a51d1d41 100755
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -26,7 +26,8 @@ dependencies = [
     "aiofiles>=24.1.0",
     "sumy>=0.11.0",
     "azure-ai-inference>=1.0.0b6",
-    "watchdog>=6.0.0"
+    "watchdog>=6.0.0",
+    "nonebot-plugin-apscheduler>=0.5.0"
 
 ]
 license = { text = "MIT, Mulan PSL v2" }