You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

94 lines
3.8KB

  1. import asyncio
  2. import json
  3. import threading
  4. from concurrent.futures import ThreadPoolExecutor
  5. import plugins
  6. from bridge.context import ContextType
  7. from bridge.reply import Reply, ReplyType
  8. from channel.chat_message import ChatMessage
  9. from common.log import logger
  10. from config import conf
  11. from plugins import *
  12. from .midjourney import MJBot, TaskType
  13. # 任务线程池
  14. task_thread_pool = ThreadPoolExecutor(max_workers=4)
  15. @plugins.register(
  16. name="linkai",
  17. desc="A plugin that supports knowledge base and midjourney drawing.",
  18. version="0.1.0",
  19. author="https://link-ai.tech",
  20. )
  21. class LinkAI(Plugin):
  22. def __init__(self):
  23. super().__init__()
  24. self.handlers[Event.ON_HANDLE_CONTEXT] = self.on_handle_context
  25. self.config = super().load_config()
  26. self.mj_bot = MJBot(self.config.get("midjourney"))
  27. logger.info("[LinkAI] inited")
  28. def on_handle_context(self, e_context: EventContext):
  29. """
  30. 消息处理逻辑
  31. :param e_context: 消息上下文
  32. """
  33. context = e_context['context']
  34. if context.type not in [ContextType.TEXT, ContextType.IMAGE]:
  35. # filter content no need solve
  36. return
  37. mj_type = self.mj_bot.judge_mj_task_type(e_context)
  38. if mj_type:
  39. # MJ作图任务处理
  40. self.mj_bot.process_mj_task(mj_type, e_context)
  41. return
  42. if self._is_chat_task(e_context):
  43. self._process_chat_task(e_context)
  44. # LinkAI 对话任务处理
  45. def _is_chat_task(self, e_context: EventContext):
  46. context = e_context['context']
  47. # 群聊应用管理
  48. return self.config.get("knowledge_base") and context.kwargs.get("isgroup")
  49. def _process_chat_task(self, e_context: EventContext):
  50. """
  51. 处理LinkAI对话任务
  52. :param e_context: 对话上下文
  53. """
  54. context = e_context['context']
  55. # 群聊应用管理
  56. group_name = context.kwargs.get("msg").from_user_nickname
  57. app_code = self._fetch_group_app_code(group_name)
  58. if app_code:
  59. context.kwargs['app_code'] = app_code
  60. def _fetch_group_app_code(self, group_name: str) -> str:
  61. """
  62. 根据群聊名称获取对应的应用code
  63. :param group_name: 群聊名称
  64. :return: 应用code
  65. """
  66. knowledge_base_config = self.config.get("knowledge_base")
  67. if knowledge_base_config and knowledge_base_config.get("group_mapping"):
  68. app_code = knowledge_base_config.get("group_mapping").get(group_name) \
  69. or knowledge_base_config.get("group_mapping").get("ALL_GROUP")
  70. return app_code
  71. def get_help_text(self, verbose=False, **kwargs):
  72. trigger_prefix = conf().get("plugin_trigger_prefix", "$")
  73. help_text = "利用midjourney来画图。\n"
  74. if not verbose:
  75. return help_text
  76. help_text += f"{trigger_prefix}mj 描述词1,描述词2 ... : 利用描述词作画,参数请放在提示词之后。\n{trigger_prefix}mjimage 描述词1,描述词2 ... : 利用描述词进行图生图,参数请放在提示词之后。\n{trigger_prefix}mjr ID: 对指定ID消息重新生成图片。\n{trigger_prefix}mju ID 图片序号: 对指定ID消息中的第x张图片进行放大。\n{trigger_prefix}mjv ID 图片序号: 对指定ID消息中的第x张图片进行变换。\n例如:\n\"{trigger_prefix}mj a little cat, white --ar 9:16\"\n\"{trigger_prefix}mjimage a white cat --ar 9:16\"\n\"{trigger_prefix}mju 1105592717188272288 2\""
  77. return help_text
  78. def _set_reply_text(self, content: str, e_context: EventContext, level: ReplyType=ReplyType.ERROR):
  79. reply = Reply(level, content)
  80. e_context["reply"] = reply
  81. e_context.action = EventAction.BREAK_PASS