Parcourir la source

Feat: add OneBot protocol tool (#7583)

Junyan Qin il y a 8 mois
Parent
commit
8807d880dc

BIN
api/core/tools/provider/builtin/onebot/_assets/icon.ico


+ 12 - 0
api/core/tools/provider/builtin/onebot/onebot.py

@@ -0,0 +1,12 @@
+from typing import Any
+
+from core.tools.errors import ToolProviderCredentialValidationError
+from core.tools.provider.builtin_tool_provider import BuiltinToolProviderController
+
+
+class OneBotProvider(BuiltinToolProviderController):
+
+    def _validate_credentials(self, credentials: dict[str, Any]) -> None:
+
+        if not credentials.get("ob11_http_url"):
+            raise ToolProviderCredentialValidationError('OneBot HTTP URL is required.')

+ 35 - 0
api/core/tools/provider/builtin/onebot/onebot.yaml

@@ -0,0 +1,35 @@
+identity:
+  author: RockChinQ
+  name: onebot
+  label:
+    en_US: OneBot v11 Protocol
+    zh_Hans: OneBot v11 协议
+  description:
+    en_US: Unofficial OneBot v11 Protocol Tool
+    zh_Hans: 非官方 OneBot v11 协议工具
+  icon: icon.ico
+credentials_for_provider:
+  ob11_http_url:
+    type: text-input
+    required: true
+    label:
+      en_US: HTTP URL
+      zh_Hans: HTTP URL
+    description:
+      en_US: Forward HTTP URL of OneBot v11
+      zh_Hans: OneBot v11 正向 HTTP URL
+    help:
+      en_US: Fill this with the HTTP URL of your OneBot server
+      zh_Hans: 请在你的 OneBot 协议端开启 正向 HTTP 并填写其 URL
+  access_token:
+    type: secret-input
+    required: false
+    label:
+      en_US: Access Token
+      zh_Hans: 访问令牌
+    description:
+      en_US: Access Token for OneBot v11 Protocol
+      zh_Hans: OneBot 协议访问令牌
+    help:
+      en_US: Fill this if you set a access token in your OneBot server
+      zh_Hans: 如果你在 OneBot 服务器中设置了 access token,请填写此项

+ 0 - 0
api/core/tools/provider/builtin/onebot/tools/__init__.py


+ 62 - 0
api/core/tools/provider/builtin/onebot/tools/send_group_msg.py

@@ -0,0 +1,62 @@
+from typing import Any, Union
+
+import requests
+
+from core.tools.entities.tool_entities import ToolInvokeMessage
+from core.tools.tool.builtin_tool import BuiltinTool
+
+
+class SendGroupMsg(BuiltinTool):
+    """OneBot v11 Tool: Send Group Message"""
+
+    def _invoke(
+            self,
+            user_id: str,
+            tool_parameters: dict[str, Any]
+        ) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]:
+
+        # Get parameters
+        send_group_id = tool_parameters.get('group_id', '')
+        
+        message = tool_parameters.get('message', '')
+        if not message:
+            return self.create_json_message(
+                {
+                    'error': 'Message is empty.'
+                }
+            )
+        
+        auto_escape = tool_parameters.get('auto_escape', False)
+
+        try:
+
+            resp = requests.post(
+                f'{self.runtime.credentials['ob11_http_url']}/send_group_msg',
+                json={
+                    'group_id': send_group_id,
+                    'message': message,
+                    'auto_escape': auto_escape
+                },
+                headers={
+                    'Authorization': 'Bearer ' + self.runtime.credentials['access_token']
+                }
+            )
+
+            if resp.status_code != 200:
+                return self.create_json_message(
+                    {
+                        'error': f'Failed to send group message: {resp.text}'
+                    }
+                )
+
+            return self.create_json_message(
+                {
+                    'response': resp.json()
+                }
+            )
+        except Exception as e:
+            return self.create_json_message(
+                {
+                    'error': f'Failed to send group message: {e}'
+                }
+            )

+ 46 - 0
api/core/tools/provider/builtin/onebot/tools/send_group_msg.yaml

@@ -0,0 +1,46 @@
+identity:
+  name: send_group_msg
+  author: RockChinQ
+  label:
+    en_US: Send Group Message
+    zh_Hans: 发送群消息
+description:
+  human:
+    en_US: Send a message to a group
+    zh_Hans: 发送消息到群聊
+  llm: A tool for sending a message segment to a group
+parameters:
+  - name: group_id
+    type: number
+    required: true
+    label:
+      en_US: Target Group ID
+      zh_Hans: 目标群 ID
+    human_description:
+      en_US: The group ID of the target group
+      zh_Hans: 目标群的群 ID
+    llm_description: The group ID of the target group
+    form: llm
+  - name: message
+    type: string
+    required: true
+    label:
+      en_US: Message
+      zh_Hans: 消息
+    human_description:
+      en_US: The message to send
+      zh_Hans: 要发送的消息。支持 CQ码(需要同时设置 auto_escape 为 true)
+    llm_description: The message to send
+    form: llm
+  - name: auto_escape
+    type: boolean
+    required: false
+    default: false
+    label:
+      en_US: Auto Escape
+      zh_Hans: 自动转义
+    human_description:
+      en_US: If true, the message will be treated as a CQ code for parsing, otherwise it will be treated as plain text for direct sending. Since Dify currently does not support passing Object-format message chains, developers can send complex message components through CQ codes.
+      zh_Hans: 若为 true 则会把 message 视为 CQ 码解析,否则视为 纯文本 直接发送。由于 Dify 目前不支持传入 Object格式 的消息,故开发者可以通过 CQ 码来发送复杂消息组件。
+    llm_description: If true, the message will be treated as a CQ code for parsing, otherwise it will be treated as plain text for direct sending.
+    form: form

+ 61 - 0
api/core/tools/provider/builtin/onebot/tools/send_private_msg.py

@@ -0,0 +1,61 @@
+from typing import Any, Union
+
+import requests
+
+from core.tools.entities.tool_entities import ToolInvokeMessage
+from core.tools.tool.builtin_tool import BuiltinTool
+
+
+class SendPrivateMsg(BuiltinTool):
+    """OneBot v11 Tool: Send Private Message"""
+
+    def _invoke(
+            self,
+            user_id: str,
+            tool_parameters: dict[str, Any]
+        ) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]:
+
+        # Get parameters
+        send_user_id = tool_parameters.get('user_id', '')
+        
+        message = tool_parameters.get('message', '')
+        if not message:
+            return self.create_json_message(
+                {
+                    'error': 'Message is empty.'
+                }
+            )
+        
+        auto_escape = tool_parameters.get('auto_escape', False)
+
+        try:
+            resp = requests.post(
+                f'{self.runtime.credentials['ob11_http_url']}/send_private_msg',
+                json={
+                    'user_id': send_user_id,
+                    'message': message,
+                    'auto_escape': auto_escape
+                },
+                headers={
+                    'Authorization': 'Bearer ' + self.runtime.credentials['access_token']
+                }
+            )
+
+            if resp.status_code != 200:
+                return self.create_json_message(
+                    {
+                        'error': f'Failed to send private message: {resp.text}'
+                    }
+                )
+        
+            return self.create_json_message(
+                {
+                    'response': resp.json()
+                }
+            )
+        except Exception as e:
+            return self.create_json_message(
+                {
+                    'error': f'Failed to send private message: {e}'
+                }
+            )

+ 46 - 0
api/core/tools/provider/builtin/onebot/tools/send_private_msg.yaml

@@ -0,0 +1,46 @@
+identity:
+  name: send_private_msg
+  author: RockChinQ
+  label:
+    en_US: Send Private Message
+    zh_Hans: 发送私聊消息
+description:
+  human:
+    en_US: Send a private message to a user
+    zh_Hans: 发送私聊消息给用户
+  llm: A tool for sending a message segment to a user in private chat
+parameters:
+  - name: user_id
+    type: number
+    required: true
+    label:
+      en_US: Target User ID
+      zh_Hans: 目标用户 ID
+    human_description:
+      en_US: The user ID of the target user
+      zh_Hans: 目标用户的用户 ID
+    llm_description: The user ID of the target user
+    form: llm
+  - name: message
+    type: string
+    required: true
+    label:
+      en_US: Message
+      zh_Hans: 消息
+    human_description:
+      en_US: The message to send
+      zh_Hans: 要发送的消息。支持 CQ码(需要同时设置 auto_escape 为 true)
+    llm_description: The message to send
+    form: llm
+  - name: auto_escape
+    type: boolean
+    required: false
+    default: false
+    label:
+      en_US: Auto Escape
+      zh_Hans: 自动转义
+    human_description:
+      en_US: If true, the message will be treated as a CQ code for parsing, otherwise it will be treated as plain text for direct sending. Since Dify currently does not support passing Object-format message chains, developers can send complex message components through CQ codes.
+      zh_Hans: 若为 true 则会把 message 视为 CQ 码解析,否则视为 纯文本 直接发送。由于 Dify 目前不支持传入 Object格式 的消息,故开发者可以通过 CQ 码来发送复杂消息组件。
+    llm_description: If true, the message will be treated as a CQ code for parsing, otherwise it will be treated as plain text for direct sending.
+    form: form