feat: 支持 LLM 对引用消息的感知 #783

This commit is contained in:
Soulter
2025-03-13 17:40:28 +08:00
parent a24eb9d9b0
commit efa287ed35
2 changed files with 56 additions and 12 deletions

View File

@@ -17,6 +17,7 @@ from astrbot.api.message_components import (
File as AstrBotFile,
Video,
At,
Reply,
)
from astrbot.core.platform.astr_message_event import MessageSesion
from astrbot.api.platform import register_platform_adapter
@@ -68,7 +69,7 @@ class TelegramPlatformAdapter(Platform):
)
message_handler = TelegramMessageHandler(
filters=filters.ALL, # receive all messages
callback=self.convert_message,
callback=self.message_handler,
)
self.application.add_handler(message_handler)
self.client = self.application.bot
@@ -104,33 +105,64 @@ class TelegramPlatformAdapter(Platform):
chat_id=update.effective_chat.id, text=self.config["start_message"]
)
async def message_handler(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
logger.debug(f"Telegram message: {update.message}")
abm = await self.convert_message(update, context)
await self.handle_msg(abm)
async def convert_message(
self, update: Update, context: ContextTypes.DEFAULT_TYPE
self, update: Update, context: ContextTypes.DEFAULT_TYPE, get_reply=True
) -> AstrBotMessage:
"""转换 Telegram 的消息对象为 AstrBotMessage 对象。
@param update: Telegram 的 Update 对象。
@param context: Telegram 的 Context 对象。
@param get_reply: 是否获取回复消息。这个参数是为了防止多个回复嵌套。
"""
message = AstrBotMessage()
# 获得是群聊还是私聊
if update.effective_chat.type == ChatType.PRIVATE:
if update.message.chat.type == ChatType.PRIVATE:
message.type = MessageType.FRIEND_MESSAGE
else:
message.type = MessageType.GROUP_MESSAGE
message.group_id = str(update.effective_chat.id)
message.group_id = str(update.message.chat.id)
if update.message.message_thread_id:
# Topic Group
message.group_id += "#" + str(update.message.message_thread_id)
message.message_id = str(update.message.message_id)
message.session_id = str(update.effective_chat.id)
message.session_id = str(update.message.chat.id)
message.sender = MessageMember(
str(update.effective_user.id), update.effective_user.username
str(update.message.from_user.id), update.message.from_user.username
)
message.self_id = str(context.bot.username)
message.raw_message = update
message.message_str = ""
message.message = []
logger.debug(f"Telegram message: {update.message}")
if update.message.reply_to_message:
# 获取回复消息
reply_update = Update(
update_id=1,
message=update.message.reply_to_message,
)
reply_abm = await self.convert_message(reply_update, context, False)
message.message.append(
Reply(
id=reply_abm.message_id,
chain=reply_abm.message,
sender_id=reply_abm.sender.user_id,
sender_nickname=reply_abm.sender.nickname,
time=reply_abm.timestamp,
message_str=reply_abm.message_str,
text=reply_abm.message_str,
qq=reply_abm.sender.user_id,
)
)
if update.message.text:
# 处理文本消息
plain_text = update.message.text
if update.message.entities:
@@ -178,7 +210,7 @@ class TelegramPlatformAdapter(Platform):
Video(file=file.file_path, path=file.file_path),
]
await self.handle_msg(message)
return message
async def handle_msg(self, message: AstrBotMessage):
message_event = TelegramPlatformEvent(

View File

@@ -17,7 +17,7 @@ from astrbot.core.star.filter.permission import PermissionTypeFilter
from astrbot.core.config.default import VERSION
from .long_term_memory import LongTermMemory
from astrbot.core import logger
from astrbot.api.message_components import Plain, Image
from astrbot.api.message_components import Plain, Image, Reply
from typing import Union
@@ -1088,12 +1088,17 @@ UID: {user_id} 此 ID 可用于设置管理员。
@filter.on_llm_request()
async def decorate_llm_req(self, event: AstrMessageEvent, req: ProviderRequest):
"""在请求 LLM 前注入人格信息、Identifier、时间等 System Prompt"""
logger.debug(req.conversation)
"""在请求 LLM 前注入人格信息、Identifier、时间、回复内容等 System Prompt"""
if self.prompt_prefix:
req.prompt = self.prompt_prefix + req.prompt
# 解析引用内容
quote = None
for comp in event.message_obj.message:
if isinstance(comp, Reply):
quote = comp
break
if self.identifier:
user_id = event.message_obj.sender.user_id
user_nickname = event.message_obj.sender.nickname
@@ -1129,6 +1134,13 @@ UID: {user_id} 此 ID 可用于设置管理员。
if begin_dialogs := persona["_begin_dialogs_processed"]:
req.contexts[:0] = begin_dialogs
if quote and quote.message_str:
if quote.sender_nickname:
sender_info = f"(Sent by {quote.sender_nickname})"
else:
sender_info = ""
req.system_prompt += f"\nUser is quoting the message{sender_info}: {quote.message_str}, please consider the context."
if self.ltm:
try:
await self.ltm.on_req_llm(event, req)