perf: add cmd enable config & fix announce request timeout & fix send card with disconnect ai platform (#1633)

* add cmd config && fix bugs

* perf: use `get`

* update bansess fix block match rule

* perf: comment for access-control session str

---------

Co-authored-by: Junyan Qin <rockchinq@gmail.com>
This commit is contained in:
Bruce
2025-08-28 12:59:50 +08:00
committed by GitHub
parent 8858f432b5
commit d9fa1cbb06
8 changed files with 54 additions and 27 deletions

View File

@@ -212,6 +212,7 @@ class DBMigrateV3Config(migration.DBMigration):
self.ap.instance_config.data['api']['port'] = self.ap.system_cfg.data['http-api']['port'] self.ap.instance_config.data['api']['port'] = self.ap.system_cfg.data['http-api']['port']
self.ap.instance_config.data['command'] = { self.ap.instance_config.data['command'] = {
'prefix': self.ap.command_cfg.data['command-prefix'], 'prefix': self.ap.command_cfg.data['command-prefix'],
'enable': self.ap.command_cfg.data['command-enable'],
'privilege': self.ap.command_cfg.data['privilege'], 'privilege': self.ap.command_cfg.data['privilege'],
} }
self.ap.instance_config.data['concurrency']['pipeline'] = self.ap.system_cfg.data['pipeline-concurrency'] self.ap.instance_config.data['concurrency']['pipeline'] = self.ap.system_cfg.data['pipeline-concurrency']

View File

@@ -30,6 +30,10 @@ class BanSessionCheckStage(stage.PipelineStage):
if sess == f'{query.launcher_type.value}_{query.launcher_id}': if sess == f'{query.launcher_type.value}_{query.launcher_id}':
found = True found = True
break break
# 使用 *_id 来表示加白/拉黑某用户的私聊和群聊场景
if sess.startswith('*_') and (sess[2:] == query.launcher_id or sess[2:] == query.sender_id):
found = True
break
ctn = False ctn = False

View File

@@ -43,7 +43,7 @@ class ChatMessageHandler(handler.MessageHandler):
query=query, query=query,
) )
) )
is_create_card = False # 判断下是否需要创建流式卡片
if event_ctx.is_prevented_default(): if event_ctx.is_prevented_default():
if event_ctx.event.reply is not None: if event_ctx.event.reply is not None:
mc = platform_message.MessageChain(event_ctx.event.reply) mc = platform_message.MessageChain(event_ctx.event.reply)
@@ -72,14 +72,17 @@ class ChatMessageHandler(handler.MessageHandler):
raise ValueError(f'未找到请求运行器: {query.pipeline_config["ai"]["runner"]["runner"]}') raise ValueError(f'未找到请求运行器: {query.pipeline_config["ai"]["runner"]["runner"]}')
if is_stream: if is_stream:
resp_message_id = uuid.uuid4() resp_message_id = uuid.uuid4()
await query.adapter.create_message_card(str(resp_message_id), query.message_event)
async for result in runner.run(query): async for result in runner.run(query):
result.resp_message_id = str(resp_message_id) result.resp_message_id = str(resp_message_id)
if query.resp_messages: if query.resp_messages:
query.resp_messages.pop() query.resp_messages.pop()
if query.resp_message_chain: if query.resp_message_chain:
query.resp_message_chain.pop() query.resp_message_chain.pop()
# 此时连接外部 AI 服务正常,创建卡片
if not is_create_card: # 只有不是第一次才创建卡片
await query.adapter.create_message_card(str(resp_message_id), query.message_event)
is_create_card = True
query.resp_messages.append(result) query.resp_messages.append(result)
self.ap.logger.info(f'对话({query.query_id})流式响应: {self.cut_str(result.readable_str())}') self.ap.logger.info(f'对话({query.query_id})流式响应: {self.cut_str(result.readable_str())}')

View File

@@ -42,12 +42,14 @@ class Processor(stage.PipelineStage):
async def generator(): async def generator():
cmd_prefix = self.ap.instance_config.data['command']['prefix'] cmd_prefix = self.ap.instance_config.data['command']['prefix']
cmd_enable = self.ap.instance_config.data['command'].get('enable', True)
if any(message_text.startswith(prefix) for prefix in cmd_prefix): if cmd_enable and any(message_text.startswith(prefix) for prefix in cmd_prefix):
async for result in self.cmd_handler.handle(query): handler_to_use = self.cmd_handler
yield result
else: else:
async for result in self.chat_handler.handle(query): handler_to_use = self.chat_handler
yield result
async for result in handler_to_use.handle(query):
yield result
return generator() return generator()

View File

@@ -45,17 +45,23 @@ class AnnouncementManager:
async def fetch_all(self) -> list[Announcement]: async def fetch_all(self) -> list[Announcement]:
"""获取所有公告""" """获取所有公告"""
resp = requests.get( try:
url='https://api.github.com/repos/langbot-app/LangBot/contents/res/announcement.json', resp = requests.get(
proxies=self.ap.proxy_mgr.get_forward_proxies(), url='https://api.github.com/repos/langbot-app/LangBot/contents/res/announcement.json',
timeout=5, proxies=self.ap.proxy_mgr.get_forward_proxies(),
) timeout=5,
obj_json = resp.json() )
b64_content = obj_json['content'] resp.raise_for_status() # 检查请求是否成功
# 解码 obj_json = resp.json()
content = base64.b64decode(b64_content).decode('utf-8') b64_content = obj_json['content']
# 解码
content = base64.b64decode(b64_content).decode('utf-8')
return [Announcement(**item) for item in json.loads(content)] return [Announcement(**item) for item in json.loads(content)]
except (requests.RequestException, json.JSONDecodeError, KeyError) as e:
self.ap.logger.warning(f"获取公告失败: {e}")
pass
return [] # 请求失败时返回空列表
async def fetch_saved(self) -> list[Announcement]: async def fetch_saved(self) -> list[Announcement]:
if not os.path.exists('data/labels/announcement_saved.json'): if not os.path.exists('data/labels/announcement_saved.json'):

View File

@@ -28,15 +28,19 @@ class VersionManager:
async def get_release_list(self) -> list: async def get_release_list(self) -> list:
"""获取发行列表""" """获取发行列表"""
rls_list_resp = requests.get( try:
url='https://api.github.com/repos/langbot-app/LangBot/releases', rls_list_resp = requests.get(
proxies=self.ap.proxy_mgr.get_forward_proxies(), url='https://api.github.com/repos/langbot-app/LangBot/releases',
timeout=5, proxies=self.ap.proxy_mgr.get_forward_proxies(),
) timeout=5,
)
rls_list = rls_list_resp.json() rls_list_resp.raise_for_status() # 检查请求是否成功
rls_list = rls_list_resp.json()
return rls_list return rls_list
except Exception as e:
self.ap.logger.warning(f"获取发行列表失败: {e}")
pass
return []
async def update_all(self): async def update_all(self):
"""检查更新并下载源码""" """检查更新并下载源码"""

View File

@@ -2,6 +2,7 @@ admins: []
api: api:
port: 5300 port: 5300
command: command:
enable: true
prefix: prefix:
- '!' - '!'
- -

View File

@@ -79,6 +79,9 @@ stages:
label: label:
en_US: Blacklist en_US: Blacklist
zh_Hans: 黑名单 zh_Hans: 黑名单
description:
en_US: Sessions in the blacklist will be ignored, the format is `{launcher_type}_{launcher_id}`remove quotes, for example `person_123` matches private chat, `group_456` matches group chat, `person_*` matches all private chats, `group_*` matches all group chats, `*_123` matches private and group chats with user ID 123
zh_Hans: 黑名单中的会话将被忽略;会话格式:`{launcher_type}_{launcher_id}`(删除引号),例如 `person_123` 匹配私聊会话,`group_456` 匹配群聊会话;`person_*` 匹配所有私聊会话,`group_*` 匹配所有群聊会话;`*_123` 匹配用户 ID 为 123 的私聊和群聊消息
type: array[string] type: array[string]
required: true required: true
default: [] default: []
@@ -86,6 +89,9 @@ stages:
label: label:
en_US: Whitelist en_US: Whitelist
zh_Hans: 白名单 zh_Hans: 白名单
description:
en_US: Only respond to sessions in the whitelist, the format is `{launcher_type}_{launcher_id}`remove quotes, for example `person_123` matches private chat, `group_456` matches group chat, `person_*` matches all private chats, `group_*` matches all group chats, `*_123` matches private and group chats with user ID 123
zh_Hans: 仅响应白名单中的会话;会话格式:`{launcher_type}_{launcher_id}`(删除引号),例如 `person_123` 匹配私聊会话,`group_456` 匹配群聊会话;`person_*` 匹配所有私聊会话,`group_*` 匹配所有群聊会话;`*_123` 匹配用户 ID 为 123 的私聊和群聊消息
type: array[string] type: array[string]
required: true required: true
default: [] default: []