feat(cross_context): 实现按互通组名称获取聊天记录

新增 `get_chat_history_by_group_name` API,允许插件按名称获取指定互通组的聊天记录。此功能增强了插件的上下文感知能力,使其能够利用跨群聊的对话历史。

主要变更:
- 在 `cross_context_api.py` 中添加了 `get_chat_history_by_group_name` 函数。
- Maizone 插件现在利用此 API 来获取跨群聊的上下文,以生成更相关的说说内容。
- 调整了配置文件模板,以反映新的互通组配置方式。
This commit is contained in:
minecraft1024a
2025-09-05 19:51:33 +08:00
parent 55abedfbf0
commit fc68958c8f
3 changed files with 76 additions and 10 deletions

View File

@@ -25,9 +25,11 @@ def get_context_groups(chat_id: str) -> Optional[List[List[str]]]:
return None return None
is_group = current_stream.group_info is not None is_group = current_stream.group_info is not None
current_chat_raw_id = ( if is_group:
current_stream.group_info.group_id if is_group else current_stream.user_info.user_id assert current_stream.group_info is not None
) current_chat_raw_id = current_stream.group_info.group_id
else:
current_chat_raw_id = current_stream.user_info.user_id
current_type = "group" if is_group else "private" current_type = "group" if is_group else "private"
for group in global_config.cross_context.groups: for group in global_config.cross_context.groups:
@@ -130,3 +132,65 @@ async def build_cross_context_s4u(
return "" return ""
return "# 跨上下文参考\n" + "\n\n".join(cross_context_messages) + "\n" return "# 跨上下文参考\n" + "\n\n".join(cross_context_messages) + "\n"
async def get_chat_history_by_group_name(group_name: str) -> str:
"""
根据互通组名字获取聊天记录
"""
target_group = None
for group in global_config.cross_context.groups:
if group.name == group_name:
target_group = group
break
if not target_group:
return f"找不到名为 {group_name} 的互通组。"
if not target_group.chat_ids:
return f"互通组 {group_name} 中没有配置任何聊天。"
chat_infos = target_group.chat_ids
chat_manager = get_chat_manager()
cross_context_messages = []
for chat_type, chat_raw_id in chat_infos:
is_group = chat_type == "group"
found_stream = None
for stream in chat_manager.streams.values():
if is_group:
if stream.group_info and stream.group_info.group_id == chat_raw_id:
found_stream = stream
break
else: # private
if stream.user_info and stream.user_info.user_id == chat_raw_id and not stream.group_info:
found_stream = stream
break
if not found_stream:
logger.warning(f"在已加载的聊天流中找不到ID为 {chat_raw_id} 的聊天。")
continue
stream_id = found_stream.stream_id
try:
messages = get_raw_msg_before_timestamp_with_chat(
chat_id=stream_id,
timestamp=time.time(),
limit=5, # 可配置
)
if messages:
chat_name = get_chat_manager().get_stream_name(stream_id) or chat_raw_id
formatted_messages, _ = build_readable_messages_with_id(
messages, timestamp_mode="relative"
)
cross_context_messages.append(f'[以下是来自"{chat_name}"的近期消息]\n{formatted_messages}')
except Exception as e:
logger.error(f"获取聊天 {chat_raw_id} 的消息失败: {e}")
continue
if not cross_context_messages:
return f"无法从互通组 {group_name} 中获取任何聊天记录。"
return "# 跨上下文参考\n" + "\n\n".join(cross_context_messages) + "\n"

View File

@@ -13,6 +13,7 @@ from src.common.logger import get_logger
import imghdr import imghdr
import asyncio import asyncio
from src.plugin_system.apis import llm_api, config_api, generator_api from src.plugin_system.apis import llm_api, config_api, generator_api
from src.plugin_system.apis.cross_context_api import get_chat_history_by_group_name
from src.chat.message_receive.chat_stream import get_chat_manager from src.chat.message_receive.chat_stream import get_chat_manager
from maim_message import UserInfo from maim_message import UserInfo
from src.llm_models.utils_model import LLMRequest from src.llm_models.utils_model import LLMRequest
@@ -87,6 +88,11 @@ class ContentService:
if context: if context:
prompt += f"\n作为参考,这里有一些最近的聊天记录:\n---\n{context}\n---" prompt += f"\n作为参考,这里有一些最近的聊天记录:\n---\n{context}\n---"
# 添加跨群聊上下文
cross_context = await get_chat_history_by_group_name("maizone_context_group")
if cross_context and "找不到名为" not in cross_context:
prompt += f"\n\n---跨群聊参考---\n{cross_context}\n---"
# 添加历史记录以避免重复 # 添加历史记录以避免重复
prompt += "\n\n---历史说说记录---\n" prompt += "\n\n---历史说说记录---\n"
history_block = await get_send_history(qq_account) history_block = await get_send_history(qq_account)
@@ -232,7 +238,7 @@ class ContentService:
for i in range(3): # 重试3次 for i in range(3): # 重试3次
try: try:
async with aiohttp.ClientSession() as session: async with aiohttp.ClientSession() as session:
async with session.get(image_url, timeout=30) as resp: async with session.get(image_url, timeout=aiohttp.ClientTimeout(total=30)) as resp:
if resp.status != 200: if resp.status != 200:
logger.error(f"下载图片失败: {image_url}, status: {resp.status}") logger.error(f"下载图片失败: {image_url}, status: {resp.status}")
await asyncio.sleep(2) await asyncio.sleep(2)

View File

@@ -1,5 +1,5 @@
[inner] [inner]
version = "6.7.1" version = "6.7.2"
#----以下是给开发人员阅读的如果你只是部署了MoFox-Bot不需要阅读---- #----以下是给开发人员阅读的如果你只是部署了MoFox-Bot不需要阅读----
#如果你想要修改配置文件请递增version的值 #如果你想要修改配置文件请递增version的值
@@ -490,13 +490,9 @@ chat_ids = [
["group", "1025509724"], # 假设这是“产品群”的ID ["group", "1025509724"], # 假设这是“产品群”的ID
["private", "123456789"] # 假设这是某个用户的私聊 ["private", "123456789"] # 假设这是某个用户的私聊
] ]
[maizone_intercom]
# QQ空间互通组配置
# 启用后,发布说说时会读取指定互通组的上下文
enable = false
# 定义QQ空间互通组 # 定义QQ空间互通组
# 同一个组的chat_id会共享上下文用于生成更相关的说说 # 同一个组的chat_id会共享上下文用于生成更相关的说说
[[maizone_intercom.groups]] [[cross_context.maizone_context_group]]
name = "Maizone默认互通组" name = "Maizone默认互通组"
chat_ids = [ chat_ids = [
["group", "111111"], # 示例群聊1 ["group", "111111"], # 示例群聊1