Skip to content

Commit

Permalink
Merge pull request #457 from 6vision/master
Browse files Browse the repository at this point in the history
feat: support linkai_bot
  • Loading branch information
zhayujie authored Jul 30, 2024
2 parents 38c256d + e7065d6 commit 5692818
Show file tree
Hide file tree
Showing 8 changed files with 607 additions and 5 deletions.
27 changes: 26 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -208,9 +208,34 @@ cookie示例:
}
}
```
### 6.LinkAI
## 三、选择应用
#### 配置项说明
```bash
{
"model": {
"type" : "linkai",
"linkai": {
"api_key": "",
"api_base": "https://api.link-ai.tech",
"app_code": "",
"model": "",
"conversation_max_tokens": 1000,
"temperature":0.75,
"top_p":0.7,
"frequency_penalty":0.0,
"presence_penalty":1.0,
"character_desc": "你是一位智能助手。"
},
}
```
+ `api_key`: LinkAI服务调用的密钥,可在 [控制台](https://link-ai.tech/console/interface) 创建
+ `app_code`: LinkAI 应用或工作流的code,选填,参考[应用创建](https://docs.link-ai.tech/platform/create-app)
+ `model`: 支持国内外常见模型,参考[模型列表](https://docs.link-ai.tech/platform/api/chat#models) ,可以留空,在[LinKAI平台](https://link-ai.tech/console/factory) 修改应用的默认模型即可
+ 其他参数含义与ChatGPT模型一致
## 三、选择应用
### 1.命令行终端
配置模板中默认启动的应用即是终端,无需任何额外配置,直接在项目目录下通过命令行执行 `python3 app.py` 便可启动程序。用户通过命令行的输入与对话模型交互,且支持流式响应效果。
Expand Down
2 changes: 2 additions & 0 deletions channel/http/http_channel.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ def handle(self, data):
query = data["msg"]
id = data["id"]
context['from_user_id'] = str(id)
context['channel'] = self
e_context = PluginManager().emit_event(EventContext(Event.ON_HANDLE_CONTEXT, {
'channel': self, 'context': query, "args": context}))
reply = e_context['reply']
Expand All @@ -135,6 +136,7 @@ async def handle_stream(self, data):
context['from_user_id'] = str(id)
context['stream'] = True
context['origin'] = data["msg"]
context['channel'] = self
e_context = PluginManager().emit_event(EventContext(Event.ON_HANDLE_CONTEXT, {
'channel': self, 'context': data["msg"], 'reply': data["msg"], "args": context}))
reply = e_context['reply']
Expand Down
48 changes: 46 additions & 2 deletions channel/wechat/wechat_channel.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import time
import itchat
import json
import re
from itchat.content import *
from channel.channel import Channel
from concurrent.futures import ThreadPoolExecutor
Expand Down Expand Up @@ -131,17 +132,49 @@ def handle_group(self, msg):

def send(self, msg, receiver):
logger.info('[WX] sendMsg={}, receiver={}'.format(msg, receiver))
itchat.send(msg, toUserName=receiver)
reply_type = self.determine_type(msg)
if reply_type == "text":
itchat.send(msg, toUserName=receiver)
elif reply_type == "img_url":
image_storage = self.dowdload_img_url(msg)
itchat.send_image(image_storage, toUserName=receiver)
elif reply_type == "file_url":
image_storage = self.dowdload_img_url(msg)
itchat.send_file(image_storage, toUserName=receiver)
else:
return None

def determine_type(self, msg):
# 正则表达式来匹配URL
url_pattern = re.compile(
r'^(?:http|ftp)s?://' # http:// or https://
r'(?:\S+(?::\S*)?@)?' # 用户名和密码
r'(?:[A-Za-z0-9-]+\.)+[A-Za-z]{2,6}' # 域名
r'(?:/?|[/?]\S+)$', re.IGNORECASE)

# 检查是否是URL
if re.match(url_pattern, msg):
# 如果是URL,进一步检查是不是图片链接
if any(msg.endswith(extension) for extension in ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.svg']):
return "img_url"
# 检查是否是其他类型的文件链接
elif any(msg.endswith(extension) for extension in
['.pdf', '.txt', '.doc', '.docx', '.xls', '.xlsx', '.zip', '.rar']):
return "img_file"
else:
return "others"
else:
return "text"

def _do_send(self, query, reply_user_id):
try:
if not query:
return
context = dict()
context['from_user_id'] = reply_user_id
context['channel'] = self
e_context = PluginManager().emit_event(EventContext(Event.ON_HANDLE_CONTEXT, {
'channel': self, 'context': query, "args": context}))

reply = e_context['reply']
if not e_context.is_pass():
reply = super().build_reply_content(e_context["context"], e_context["args"])
Expand Down Expand Up @@ -178,11 +211,22 @@ def _do_send_img(self, query, context):
except Exception as e:
logger.exception(e)


def dowdload_img_url(self, url):
pic_res = requests.get(url, stream=True)
image_storage = io.BytesIO()
for block in pic_res.iter_content(1024):
image_storage.write(block)
image_storage.seek(0)
return image_storage


def _do_send_group(self, query, msg):
if not query:
return
context = dict()
context['from_user_id'] = msg['User']['UserName']
context['channel'] = self
e_context = PluginManager().emit_event(EventContext(Event.ON_HANDLE_CONTEXT, {
'channel': self, 'context': query, "args": context}))
reply = e_context['reply']
Expand Down
3 changes: 2 additions & 1 deletion common/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,5 @@
CHATGPT = "chatgpt"
BAIDU = "baidu"
BING = "bing"
BARD = "bard"
BARD = "bard"
LINKAI = "linkai"
13 changes: 13 additions & 0 deletions config-template.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,19 @@
"presence_penalty":1.0,
"character_desc": "你是ChatGPT, 一个由OpenAI训练的大型语言模型, 你旨在回答并解决人们的任何问题,并且可以使用多种语言与人交流。当问起你是谁的时候,要附加告诉提问人,输入 #清除记忆 可以开始新的话题探索。输入 画xx 可以为你画一张图片。"
},
"linkai": {
"api_key": "",
"api_base": "https://api.link-ai.tech",
"app_code": "",
"model": "",
"proxy": "",
"conversation_max_tokens": 1000,
"temperature":0.75,
"top_p":0.7,
"frequency_penalty":0.0,
"presence_penalty":1.0,
"character_desc": "你是ChatGPT, 一个由OpenAI训练的大型语言模型, 你旨在回答并解决人们的任何问题,并且可以使用多种语言与人交流。当问起你是谁的时候,要附加告诉提问人,输入 #清除记忆 可以开始新的话题探索。输入 画xx 可以为你画一张图片。"
},
"baidu": {
"acs_token": "YOUR ACS TOKEN",
"cookie": "YOUR COOKIE"
Expand Down
Loading

0 comments on commit 5692818

Please sign in to comment.