feat: support langchain powered by flowise

Bump requests from 2.28.2 to 2.31.0

Bumps [requests](https://github.com/psf/requests) from 2.28.2 to 2.31.0.
- [Release notes](https://github.com/psf/requests/releases)
- [Changelog](https://github.com/psf/requests/blob/main/HISTORY.md)
- [Commits](https://github.com/psf/requests/compare/v2.28.2...v2.31.0)

---
updated-dependencies:
- dependency-name: requests
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
This commit is contained in:
hibobmaster 2023-05-26 20:31:52 +08:00
parent 6ff585d402
commit 600c5e161a
No known key found for this signature in database
GPG Key ID: 316B77D7914D713C
7 changed files with 86 additions and 11 deletions

View File

@ -13,4 +13,6 @@ BING_AUTH_COOKIE="xxxxxxxxxxxxxxxxxxx" # _U cookie, Optional, for Bing Image Cre
MARKDOWN_FORMATTED="true" # Optional MARKDOWN_FORMATTED="true" # Optional
OUTPUT_FOUR_IMAGES="true" # Optional OUTPUT_FOUR_IMAGES="true" # Optional
IMPORT_KEYS_PATH="element-keys.txt" # Optional IMPORT_KEYS_PATH="element-keys.txt" # Optional
IMPORT_KEYS_PASSWORD="xxxxxxx" # Optional IMPORT_KEYS_PASSWORD="xxxxxxx" # Optional
FLOWISE_API_URL="http://localhost:3000/api/v1/prediction/xxxx" # Optional
FLOWISE_API_KEY="xxxxxxxxxxxxxxxxxxxxxxx" # Optional

View File

@ -1,13 +1,13 @@
## Introduction ## Introduction
This is a simple Matrix bot that uses OpenAI's GPT API and Bing AI and Google Bard to generate responses to user inputs. The bot responds to five types of prompts: `!gpt`, `!chat` and `!bing` and `!pic` and `!bard` depending on the first word of the prompt. This is a simple Matrix bot that uses OpenAI's GPT API and Bing AI and Google Bard to generate responses to user inputs. The bot responds to six types of prompts: `!gpt`, `!chat` and `!bing` and `!pic` and `!bard` and `!lc` depending on the first word of the prompt.
![Bing](https://user-images.githubusercontent.com/32976627/231073146-3e380217-a6a2-413d-9203-ab36965b909d.png) ![Bing](https://user-images.githubusercontent.com/32976627/231073146-3e380217-a6a2-413d-9203-ab36965b909d.png)
![image](https://user-images.githubusercontent.com/32976627/232036790-e830145c-914e-40be-b3e6-c02cba93329c.png) ![image](https://user-images.githubusercontent.com/32976627/232036790-e830145c-914e-40be-b3e6-c02cba93329c.png)
![ChatGPT](https://i.imgur.com/kK4rnPf.jpeg) ![ChatGPT](https://i.imgur.com/kK4rnPf.jpeg)
## Feature ## Feature
1. Support Openai ChatGPT and Bing AI and Google Bard(US only at the moment) 1. Support Openai ChatGPT and Bing AI and Google Bard and Langchain([Flowise](https://github.com/FlowiseAI/Flowise))
2. Support Bing Image Creator 2. Support Bing Image Creator
3. Support E2E Encrypted Room 3. Support E2E Encrypted Room
4. Colorful code blocks 4. Colorful code blocks
@ -26,7 +26,7 @@ sudo docker compose up -d
<hr> <hr>
Normal Method:<br> Normal Method:<br>
system dependece: `libolm-dev` system dependece: <code>libolm-dev</code>
1. Clone the repository and create virtual environment: 1. Clone the repository and create virtual environment:
@ -99,7 +99,10 @@ To interact with the bot, simply send a message to the bot in the Matrix room wi
``` ```
!bard Building a website can be done in 10 simple steps !bard Building a website can be done in 10 simple steps
``` ```
- `!lc` To chat using langchain api endpoint
```
!lc 人生如音乐,欢乐且自由
```
- `!pic` To generate an image from Microsoft Bing - `!pic` To generate an image from Microsoft Bing
``` ```

53
bot.py
View File

@ -21,6 +21,7 @@ from send_image import send_room_image
from send_message import send_room_message from send_message import send_room_message
from v3 import Chatbot from v3 import Chatbot
from bard import Bardbot from bard import Bardbot
from flowise import flowise_query
logger = getlogger() logger = getlogger()
@ -45,6 +46,8 @@ class Bot:
output_four_images: Union[bool, None] = False, output_four_images: Union[bool, None] = False,
import_keys_path: Optional[str] = None, import_keys_path: Optional[str] = None,
import_keys_password: Optional[str] = None, import_keys_password: Optional[str] = None,
flowise_api_url: Optional[str] = None,
flowise_api_key: Optional[str] = None
): ):
if (homeserver is None or user_id is None if (homeserver is None or user_id is None
or device_id is None): or device_id is None):
@ -66,6 +69,8 @@ class Bot:
self.chatgpt_api_endpoint = chatgpt_api_endpoint self.chatgpt_api_endpoint = chatgpt_api_endpoint
self.import_keys_path = import_keys_path self.import_keys_path = import_keys_path
self.import_keys_password = import_keys_password self.import_keys_password = import_keys_password
self.flowise_api_url = flowise_api_url
self.flowise_api_key = flowise_api_key
self.session = aiohttp.ClientSession() self.session = aiohttp.ClientSession()
@ -124,6 +129,7 @@ class Bot:
self.bing_prog = re.compile(r"^\s*!bing\s*(.+)$") self.bing_prog = re.compile(r"^\s*!bing\s*(.+)$")
self.bard_prog = re.compile(r"^\s*!bard\s*(.+)$") self.bard_prog = re.compile(r"^\s*!bard\s*(.+)$")
self.pic_prog = re.compile(r"^\s*!pic\s*(.+)$") self.pic_prog = re.compile(r"^\s*!pic\s*(.+)$")
self.lc_prog = re.compile(r"^\s*!lc\s*(.+)$")
self.help_prog = re.compile(r"^\s*!help\s*.*$") self.help_prog = re.compile(r"^\s*!help\s*.*$")
# initialize chatbot and chatgpt_api_endpoint # initialize chatbot and chatgpt_api_endpoint
@ -281,6 +287,24 @@ class Bot:
logger.error(e, exc_info=True) logger.error(e, exc_info=True)
await send_room_message(self.client, room_id, reply_message={e}) await send_room_message(self.client, room_id, reply_message={e})
# lc command
if self.flowise_api_url is not None:
m = self.lc_prog.match(content_body)
if m:
prompt = m.group(1)
try:
asyncio.create_task(self.lc(
room_id,
reply_to_event_id,
prompt,
sender_id,
raw_user_message
)
)
except Exception as e:
logger.error(e, exc_info=True)
await send_room_message(self.client, room_id, reply_message={e})
# help command # help command
h = self.help_prog.match(content_body) h = self.help_prog.match(content_body)
if h: if h:
@ -598,6 +622,26 @@ class Bot:
except Exception as e: except Exception as e:
logger.error(e, exc_info=True) logger.error(e, exc_info=True)
# !lc command
async def lc(self, room_id, reply_to_event_id, prompt, sender_id,
raw_user_message) -> None:
try:
# sending typing state
await self.client.room_typing(room_id)
if self.flowise_api_key is not None:
headers = {'Authorization': f'Bearer {self.flowise_api_key}'}
response = await asyncio.to_thread(flowise_query,
self.flowise_api_url, prompt, headers)
else:
response = await asyncio.to_thread(flowise_query,
self.flowise_api_url, prompt)
await send_room_message(self.client, room_id, reply_message=response,
reply_to_event_id="", sender_id=sender_id,
user_message=raw_user_message,
markdown_formatted=self.markdown_formatted)
except Exception as e:
raise Exception(e)
# !pic command # !pic command
async def pic(self, room_id, prompt): async def pic(self, room_id, prompt):
@ -629,11 +673,12 @@ class Bot:
try: try:
# sending typing state # sending typing state
await self.client.room_typing(room_id) await self.client.room_typing(room_id)
help_info = "!gpt [content], generate response without context conversation\n" + \ help_info = "!gpt [prompt], generate response without context conversation\n" + \
"!chat [content], chat with context conversation\n" + \ "!chat [prompt], chat with context conversation\n" + \
"!bing [content], chat with context conversation powered by Bing AI\n" + \ "!bing [prompt], chat with context conversation powered by Bing AI\n" + \
"!bard [content], chat with Google's Bard\n" + \ "!bard [prompt], chat with Google's Bard\n" + \
"!pic [prompt], Image generation by Microsoft Bing\n" + \ "!pic [prompt], Image generation by Microsoft Bing\n" + \
"!lc [prompt], chat using langchain api\n" + \
"!help, help message" # noqa: E501 "!help, help message" # noqa: E501
await send_room_message(self.client, room_id, reply_message=help_info) await send_room_message(self.client, room_id, reply_message=help_info)

View File

@ -13,5 +13,7 @@
"markdown_formatted": true, "markdown_formatted": true,
"output_four_images": true, "output_four_images": true,
"import_keys_path": "element-keys.txt", "import_keys_path": "element-keys.txt",
"import_keys_password": "xxxxxxxxx" "import_keys_password": "xxxxxxxxx",
"flowise_api_url": "http://localhost:3000/api/v1/prediction/6deb3c89-45bf-4ac4-a0b0-b2d5ef249d21",
"flowise_api_key": "U3pe0bbVDWOyoJtsDzFJjRvHKTP3FRjODwuM78exC3A="
} }

19
flowise.py Normal file
View File

@ -0,0 +1,19 @@
import requests
def flowise_query(api_url: str, prompt: str, headers: dict = None) -> str:
"""
Sends a query to the Flowise API and returns the response.
Args:
api_url (str): The URL of the Flowise API.
prompt (str): The question to ask the API.
Returns:
str: The response from the API.
"""
if headers:
response = requests.post(api_url, json={"question": prompt},
headers=headers, timeout=120)
else:
response = requests.post(api_url, json={"question": prompt}, timeout=120)
return response.text

View File

@ -29,6 +29,8 @@ async def main():
import_keys_path=config.get('import_keys_path'), import_keys_path=config.get('import_keys_path'),
import_keys_password=config.get( import_keys_password=config.get(
'import_keys_password'), 'import_keys_password'),
flowise_api_url=config.get('flowise_api_url'),
flowise_api_key=config.get('flowise_api_key'),
) )
if config.get('import_keys_path') and \ if config.get('import_keys_path') and \
config.get('import_keys_password') is not None: config.get('import_keys_password') is not None:
@ -57,6 +59,8 @@ async def main():
import_keys_path=os.environ.get("IMPORT_KEYS_PATH"), import_keys_path=os.environ.get("IMPORT_KEYS_PATH"),
import_keys_password=os.environ.get( import_keys_password=os.environ.get(
"IMPORT_KEYS_PASSWORD"), "IMPORT_KEYS_PASSWORD"),
flowise_api_url=os.environ.get("FLOWISE_API_URL"),
flowise_api_key=os.environ.get("FLOWISE_API_KEY"),
) )
if os.environ.get("IMPORT_KEYS_PATH") \ if os.environ.get("IMPORT_KEYS_PATH") \
and os.environ.get("IMPORT_KEYS_PASSWORD") is not None: and os.environ.get("IMPORT_KEYS_PASSWORD") is not None:

View File

@ -39,7 +39,7 @@ python-magic==0.4.27
python-olm==3.1.3 python-olm==3.1.3
python-socks==2.2.0 python-socks==2.2.0
regex==2023.3.23 regex==2023.3.23
requests==2.28.2 requests==2.31.0
rfc3986==1.5.0 rfc3986==1.5.0
six==1.16.0 six==1.16.0
sniffio==1.3.0 sniffio==1.3.0