From 27ba575547bf952af466ad82e512f1636388e684 Mon Sep 17 00:00:00 2001 From: taylor Date: Fri, 11 Oct 2024 23:24:28 +0800 Subject: [PATCH] add: init --- .idea/.gitignore | 8 ++ .../inspectionProfiles/profiles_settings.xml | 6 + .idea/maubot-llmplus.iml | 10 ++ .idea/misc.xml | 4 + .idea/modules.xml | 8 ++ .idea/vcs.xml | 6 + base-config.yaml | 32 +++++ main.py | 16 +++ maubot-llmplus/ai_bot.py | 124 ++++++++++++++++++ maubot.yaml | 11 ++ requirement.txt | 1 + 11 files changed, 226 insertions(+) create mode 100644 .idea/.gitignore create mode 100644 .idea/inspectionProfiles/profiles_settings.xml create mode 100644 .idea/maubot-llmplus.iml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml create mode 100644 base-config.yaml create mode 100644 main.py create mode 100644 maubot-llmplus/ai_bot.py create mode 100644 maubot.yaml create mode 100644 requirement.txt diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/maubot-llmplus.iml b/.idea/maubot-llmplus.iml new file mode 100644 index 0000000..74d515a --- /dev/null +++ b/.idea/maubot-llmplus.iml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..90553d3 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..124c4eb --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/base-config.yaml b/base-config.yaml new file mode 100644 index 0000000..82a3bf2 --- /dev/null +++ b/base-config.yaml @@ -0,0 +1,32 @@ +allowed_users: [] + +use_platform: local + +name: + +reply_in_thread: + +enable_multi_user: + +system_prompt: + +platforms: + local: + type: ollama + url: http://localhost:11434 + api_key: + model: llama3.2 + max_words: 1000 + openai: + url: + api_key: + model: + max_tokens: + max_words: + temperature: + anthropic: + url: + api_key: + max_tokens: + model: + max_words: diff --git a/main.py b/main.py new file mode 100644 index 0000000..5596b44 --- /dev/null +++ b/main.py @@ -0,0 +1,16 @@ +# This is a sample Python script. + +# Press Shift+F10 to execute it or replace it with your code. +# Press Double Shift to search everywhere for classes, files, tool windows, actions, and settings. + + +def print_hi(name): + # Use a breakpoint in the code line below to debug your script. + print(f'Hi, {name}') # Press Ctrl+F8 to toggle the breakpoint. + + +# Press the green button in the gutter to run the script. +if __name__ == '__main__': + print_hi('PyCharm') + +# See PyCharm help at https://www.jetbrains.com/help/pycharm/ diff --git a/maubot-llmplus/ai_bot.py b/maubot-llmplus/ai_bot.py new file mode 100644 index 0000000..508e8be --- /dev/null +++ b/maubot-llmplus/ai_bot.py @@ -0,0 +1,124 @@ +import re +from typing import Type + +from maubot import Plugin +from maubot.handlers import event +from mautrix.types import EventType, MessageType, MessageEvent, RelationType, TextMessageEventContent, Format +from mautrix.util import markdown +from mautrix.util.config import BaseProxyConfig, ConfigUpdateHelper + +""" +配置文件加载 +""" +class Config(BaseProxyConfig): + def db_update(self, helper: ConfigUpdateHelper) -> None: + helper.copy("allowed_users") + helper.copy("use_platform") + helper.copy("name") + helper.copy("reply_in_thread") + helper.copy("enable_multi_user") + helper.copy("system_prompt") + helper.copy("platforms") + +class AiBot(Plugin): + + # name of the bot + name: str + + + async def start(self) -> None: + # 加载并更新配置 + self.config.load_and_update() + # 决定当前机器人的名称 + + """ + 判断sender是否是allowed_users中的成员 + 如果是, 则可以发送消息给AI + """ + def is_allow(self, sender: str) -> bool: + # 如果列表中没有元素, 直接返回True + if len(self.config['allowed_users']) <= 0: + return True + + for u in self.config['allowed_users']: + self.log.debug(f"bot: {sender} -> {u}") + # 如果sender是allowed_user中的一员, 那么就允许发送消息给AI + if re.Match(u, sender): + return True + self.log.debug(f"{sender} doesn't match allowed_users") + pass + + """ + 判断是否应该让AI进行回应 + 回应条件: + 前提条件: + 消息发送者不是机器人本身 or 不是编辑消息 or 不是消息类型 + 1. @AI机器人时 + 2. 消息中呼唤 name变量的值的时候 + 3. 回复机器人消息时 + 4. 当聊天室中只有两个人, 并且其中一个是机器人时 + 5. 在thread中 + """ + async def should_respond(self, event: MessageEvent) -> bool: + # 发送者是机器人本身, 返回False + if event.sender == self.client.mxid: + return False + + # 判断这个用户是否在允许列表中, 不存在返回False + # 如果列表为空, 继续往下执行 + if not self.is_allow(event.sender): + return False + + # 不是编辑消息 or 不是消息类型, 返回false + if(event.content['msgtype'] != MessageType.TEXT or + event.content.relates_to['rel_type'] == RelationType.REPLACE): + return False + + # 检查是否发送消息中有带上机器人的别名 + if re.search("(^|\s)(@)?" + self.name + "([ :,.!?]|$)", event.content.body, re.IGNORECASE): + return True + + # 当聊天室只有两个人并且其中一个是机器人时 + if len(await self.client.get_joined_members(event.room_id)) == 2: + return True + + # 在thread中时 + if self.config['reply_in_thread'] and event.content.relates_to.rel_type == RelationType.THREAD: + parent_event = await self.client.get_event(room_id=event.room_id, event_id=event.content.get_thread_parent()) + return await self.should_respond(parent_event) + + # 如果是回复消息 + if event.content.relates_to.in_reply_to: + parent_event = await self.client.get_event(room_id=event.room_id, event_id=event.content.get_reply_to()) + if parent_event.sender == self.client.mxid: + return True + + async def get_context(self, event: MessageEvent): + return None + + async def _ai_call(self, prompt): + return None + + @event.on(EventType.ROOM_MESSAGE) + async def on_message(self, event: MessageEvent) -> None: + if not await self.should_respond(event): + return + + try: + await event.mark_read() + resp_content = "response test" + + await self.client.set_typing(event.room_id, timeout=99999) + response = TextMessageEventContent(msgtype=MessageType.NOTICE, body = resp_content, format = Format.HTML, + formatted_body = markdown.render(resp_content)) + await event.respond(response) + except Exception as e: + pass + + return None; + + @classmethod + def get_config_class(cls) -> Type[BaseProxyConfig]: + return Config + + diff --git a/maubot.yaml b/maubot.yaml new file mode 100644 index 0000000..fb6583e --- /dev/null +++ b/maubot.yaml @@ -0,0 +1,11 @@ +maubot: 0.1.0 +id: org.taylorxie.llmplus +version: 1.0.0 +license: MIT +modules: + - maubot-llmplus +main_class: AiBot +config: true +extra_files: + - base-config.yaml +database: true diff --git a/requirement.txt b/requirement.txt new file mode 100644 index 0000000..23329d7 --- /dev/null +++ b/requirement.txt @@ -0,0 +1 @@ +maubot==0.4.2 \ No newline at end of file