diff --git a/intergrations/chatgpt-on-wechat/plugins/README.md b/intergrations/chatgpt-on-wechat/plugins/README.md new file mode 100644 index 00000000000..0f1c47968c7 --- /dev/null +++ b/intergrations/chatgpt-on-wechat/plugins/README.md @@ -0,0 +1,57 @@ +RAGFlow Chat Plugin for ChatGPT-on-WeChat +========================================= + +This folder contains the source code for the `ragflow_chat` plugin, which extends the core functionality of the RAGFlow API to support conversational interactions using Retrieval-Augmented Generation (RAG). This plugin integrates seamlessly with the [ChatGPT-on-WeChat](https://github.com/zhayujie/chatgpt-on-wechat) project, enabling WeChat and other platforms to leverage the knowledge retrieval capabilities provided by RAGFlow in chat interactions. + +### Features +* **Conversational Interactions**: Combine WeChat's conversational interface with powerful RAG (Retrieval-Augmented Generation) capabilities. +* **Knowledge-Based Responses**: Enrich conversations by retrieving relevant data from external knowledge sources and incorporating them into chat responses. +* **Multi-Platform Support**: Works across WeChat, WeCom, and various other platforms supported by the ChatGPT-on-WeChat framework. + +### Plugin vs. ChatGPT-on-WeChat Configurations +**Note**: There are two distinct configuration files used in this setup—one for the ChatGPT-on-WeChat core project and another specific to the `ragflow_chat` plugin. It is important to configure both correctly to ensure smooth integration. + +#### ChatGPT-on-WeChat Root Configuration (`config.json`) +This file is located in the root directory of the [ChatGPT-on-WeChat](https://github.com/zhayujie/chatgpt-on-wechat) project and is responsible for defining the communication channels and overall behavior. For example, it handles the configuration for WeChat, WeCom, and other services like Feishu and DingTalk. + +Example `config.json` (for WeChat channel): +```json +{ + "channel_type": "wechatmp", + "wechatmp_app_id": "YOUR_APP_ID", + "wechatmp_app_secret": "YOUR_APP_SECRET", + "wechatmp_token": "YOUR_TOKEN", + "wechatmp_port": 80, + ... +} +``` + +This file can also be modified to support other communication platforms, such as: +- **Personal WeChat** (`channel_type: wx`) +- **WeChat Public Account** (`wechatmp` or `wechatmp_service`) +- **WeChat Work (WeCom)** (`wechatcom_app`) +- **Feishu** (`feishu`) +- **DingTalk** (`dingtalk`) + +For detailed configuration options, see the official [LinkAI documentation](https://docs.link-ai.tech/cow/multi-platform/wechat-mp). + +#### RAGFlow Chat Plugin Configuration (`plugins/ragflow_chat/config.json`) +This configuration is specific to the `ragflow_chat` plugin and is used to set up communication with the RAGFlow server. Ensure that your RAGFlow server is running, and update the plugin's `config.json` file with your server details: + +Example `config.json` (for `ragflow_chat`): +```json +{ + "ragflow_api_key": "YOUR_API_KEY", + "ragflow_host": "127.0.0.1:80" +} +``` + +This file must be configured to point to your RAGFlow instance, with the `ragflow_api_key` and `ragflow_host` fields set appropriately. The `ragflow_host` is typically your server's address and port number, and the `ragflow_api_key` is obtained from your RAGFlow API setup. + +### Requirements +Before you can use this plugin, ensure the following are in place: + +1. You have installed and configured [ChatGPT-on-WeChat](https://github.com/zhayujie/chatgpt-on-wechat). +2. You have deployed and are running the [RAGFlow](https://github.com/jina-ai/ragflow) server. + +Make sure both `config.json` files (ChatGPT-on-WeChat and RAGFlow Chat Plugin) are correctly set up as per the examples above. diff --git a/intergrations/chatgpt-on-wechat/plugins/__init__.py b/intergrations/chatgpt-on-wechat/plugins/__init__.py new file mode 100644 index 00000000000..4b79b693129 --- /dev/null +++ b/intergrations/chatgpt-on-wechat/plugins/__init__.py @@ -0,0 +1 @@ +from .ragflow_chat import * diff --git a/intergrations/chatgpt-on-wechat/plugins/config.json b/intergrations/chatgpt-on-wechat/plugins/config.json new file mode 100644 index 00000000000..b09ff72f27a --- /dev/null +++ b/intergrations/chatgpt-on-wechat/plugins/config.json @@ -0,0 +1,4 @@ +{ + "api_key": "ragflow-***", + "host_address": "127.0.0.1:80" +} diff --git a/intergrations/chatgpt-on-wechat/plugins/ragflow_chat.py b/intergrations/chatgpt-on-wechat/plugins/ragflow_chat.py new file mode 100644 index 00000000000..3d8b43ea685 --- /dev/null +++ b/intergrations/chatgpt-on-wechat/plugins/ragflow_chat.py @@ -0,0 +1,114 @@ +import requests +import json +from bridge.context import Context, ContextType # Import Context, ContextType +from bridge.reply import Reply, ReplyType # Import Reply, ReplyType +from bridge import * +from common.log import logger +from config import conf +from plugins import Plugin, register # Import Plugin and register +from plugins.event import Event, EventContext, EventAction # Import event-related classes + +@register(name="RAGFlowChat", desc="Use RAGFlow API to chat", version="1.0", author="Your Name") +class RAGFlowChat(Plugin): + def __init__(self): + super().__init__() + # Load plugin configuration + self.cfg = self.load_config() + # Bind event handling function + self.handlers[Event.ON_HANDLE_CONTEXT] = self.on_handle_context + # Store conversation_id for each user + self.conversations = {} + logger.info("[RAGFlowChat] Plugin initialized") + + def on_handle_context(self, e_context: EventContext): + context = e_context['context'] + if context.type != ContextType.TEXT: + return # Only process text messages + + user_input = context.content.strip() + session_id = context['session_id'] + + # Call RAGFlow API to get a reply + reply_text = self.get_ragflow_reply(user_input, session_id) + if reply_text: + reply = Reply() + reply.type = ReplyType.TEXT + reply.content = reply_text + e_context['reply'] = reply + e_context.action = EventAction.BREAK_PASS # Skip the default processing logic + else: + # If no reply is received, pass to the next plugin or default logic + e_context.action = EventAction.CONTINUE + + def get_ragflow_reply(self, user_input, session_id): + # Get API_KEY and host address from the configuration + api_key = self.cfg.get("api_key") + host_address = self.cfg.get("host_address") + user_id = session_id # Use session_id as user_id + + if not api_key or not host_address: + logger.error("[RAGFlowChat] Missing configuration") + return "The plugin configuration is incomplete. Please check the configuration." + + headers = { + "Authorization": f"Bearer {api_key}", + "Content-Type": "application/json" + } + + # Step 1: Get or create conversation_id + conversation_id = self.conversations.get(user_id) + if not conversation_id: + # Create a new conversation + url_new_conversation = f"http://{host_address}/v1/api/new_conversation" + params_new_conversation = { + "user_id": user_id + } + try: + response = requests.get(url_new_conversation, headers=headers, params=params_new_conversation) + logger.debug(f"[RAGFlowChat] New conversation response: {response.text}") + if response.status_code == 200: + data = response.json() + if data.get("retcode") == 0: + conversation_id = data["data"]["id"] + self.conversations[user_id] = conversation_id + else: + logger.error(f"[RAGFlowChat] Failed to create conversation: {data.get('retmsg')}") + return f"Sorry, unable to create a conversation: {data.get('retmsg')}" + else: + logger.error(f"[RAGFlowChat] HTTP error when creating conversation: {response.status_code}") + return f"Sorry, unable to connect to RAGFlow API (create conversation). HTTP status code: {response.status_code}" + except Exception as e: + logger.exception(f"[RAGFlowChat] Exception when creating conversation: {e}") + return f"Sorry, an internal error occurred: {str(e)}" + + # Step 2: Send the message and get a reply + url_completion = f"http://{host_address}/v1/api/completion" + payload_completion = { + "conversation_id": conversation_id, + "messages": [ + { + "role": "user", + "content": user_input + } + ], + "quote": False, + "stream": False + } + + try: + response = requests.post(url_completion, headers=headers, json=payload_completion) + logger.debug(f"[RAGFlowChat] Completion response: {response.text}") + if response.status_code == 200: + data = response.json() + if data.get("retcode") == 0: + answer = data["data"]["answer"] + return answer + else: + logger.error(f"[RAGFlowChat] Failed to get answer: {data.get('retmsg')}") + return f"Sorry, unable to get a reply: {data.get('retmsg')}" + else: + logger.error(f"[RAGFlowChat] HTTP error when getting answer: {response.status_code}") + return f"Sorry, unable to connect to RAGFlow API (get reply). HTTP status code: {response.status_code}" + except Exception as e: + logger.exception(f"[RAGFlowChat] Exception when getting answer: {e}") + return f"Sorry, an internal error occurred: {str(e)}" diff --git a/intergrations/chatgpt-on-wechat/plugins/requirements.txt b/intergrations/chatgpt-on-wechat/plugins/requirements.txt new file mode 100644 index 00000000000..f2293605cf1 --- /dev/null +++ b/intergrations/chatgpt-on-wechat/plugins/requirements.txt @@ -0,0 +1 @@ +requests