Files
abot/plugins/member_context/main.py

167 lines
6.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from typing import Dict, Any, Tuple, Optional, List
from base.plugin_common.message_plugin_interface import MessagePluginInterface
from base.plugin_common.plugin_interface import PluginStatus
from plugins.member_context.service import MemberContextService
class MemberContextPlugin(MessagePluginInterface):
"""群成员交互摘要后台插件"""
FEATURE_KEY = "MEMBER_CONTEXT_CAPABILITY"
FEATURE_DESCRIPTION = "🧠 成员交互摘要 [后台AI提取仅对启用群生效]"
@property
def name(self) -> str:
return "成员交互摘要"
@property
def version(self) -> str:
return "1.0.0"
@property
def description(self) -> str:
return "为群成员生成后台交互摘要,并按群功能开关控制"
@property
def author(self) -> str:
return "ABOT Team"
@property
def commands(self) -> List[str]:
return []
@property
def feature_key(self) -> Optional[str]:
return self.FEATURE_KEY
@property
def feature_description(self) -> Optional[str]:
return self.FEATURE_DESCRIPTION
def __init__(self):
super().__init__()
self.feature = self.register_feature()
self.service: Optional[MemberContextService] = None
def initialize(self, context: Dict[str, Any]) -> bool:
self.LOG.debug(f"正在初始化 {self.name} 插件...")
self.service = MemberContextService(context["db_manager"], self._config)
self.LOG.debug(f"{self.name} 插件初始化完成")
return True
def start(self) -> bool:
self.LOG.debug(f"[{self.name}] 插件已启动")
self.status = PluginStatus.RUNNING
return True
def stop(self) -> bool:
self.LOG.info(f"[{self.name}] 插件已停止")
self.status = PluginStatus.STOPPED
return True
def can_process(self, message: Dict[str, Any]) -> bool:
return False
async def process_message(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]:
return False, None
def get_schedule_actions(self) -> List[Dict[str, Any]]:
"""把成员画像日/周/月刷新动作声明给统一调度中心。"""
schedule_cfg = self._config.get("schedule", {}) or {}
refresh_times = schedule_cfg.get("refresh_times", []) or []
weekly_refresh_time = str(schedule_cfg.get("weekly_refresh_time", "") or "").strip()
monthly_refresh_time = str(schedule_cfg.get("monthly_refresh_time", "") or "").strip()
actions: List[Dict[str, Any]] = []
if refresh_times:
actions.append(
{
"action_key": "daily_refresh",
"name": "成员画像日刷新",
"description": "刷新启用群的成员交互摘要(日任务)",
"trigger_type": "at_times",
"trigger_config": {"time_list": refresh_times},
"target_scope": "all_enabled_groups",
"target_config": {},
"payload": {},
"default_enabled": True,
}
)
if weekly_refresh_time:
actions.append(
{
"action_key": "weekly_refresh",
"name": "成员画像周刷新",
"description": "刷新启用群的成员交互摘要(周任务,含周摘要)",
"trigger_type": "every_week_time",
"trigger_config": {"weekday": 6, "time_str": weekly_refresh_time},
"target_scope": "all_enabled_groups",
"target_config": {},
"payload": {},
"default_enabled": True,
}
)
if monthly_refresh_time:
actions.append(
{
"action_key": "monthly_refresh",
"name": "成员画像月刷新",
"description": "刷新启用群的成员交互摘要(月任务,含月摘要)",
"trigger_type": "every_month_last_day_time",
"trigger_config": {"time_str": monthly_refresh_time},
"target_scope": "all_enabled_groups",
"target_config": {},
"payload": {},
"default_enabled": True,
}
)
return actions
async def run_scheduled_action(self, action_key: str, context: Dict[str, Any]) -> Dict[str, Any]:
"""执行成员画像后台调度动作。"""
if not self.service:
return {"success": False, "summary": "服务未初始化", "detail": {}}
if action_key not in {"daily_refresh", "weekly_refresh", "monthly_refresh"}:
return {"success": False, "summary": f"不支持的动作: {action_key}", "detail": {"action_key": action_key}}
# 兼容“指定群执行”的场景;若未指定则沿用全量刷新逻辑。
target_groups = [str(g).strip() for g in (context.get("target_groups") or []) if str(g).strip()]
# 调度层补偿策略:
# 1. 周任务除了补周摘要,也顺手检查月摘要缺口;
# 2. 月任务先补齐缺失周摘要,再继续补月摘要,避免“月摘要依赖周摘要但周摘要没补上”;
# 3. 日任务仍保持轻量,不主动放大到全量周/月补偿。
enable_weekly = action_key in {"weekly_refresh", "monthly_refresh"}
enable_monthly = action_key in {"weekly_refresh", "monthly_refresh"}
try:
if target_groups:
groups = 0
members = 0
skipped = 0
for group_id in target_groups:
result = self.service.refresh_group_contexts(
group_id,
enable_weekly_digest=enable_weekly,
enable_monthly_digest=enable_monthly,
)
if result.get("disabled"):
continue
groups += 1
members += int(result.get("refreshed", 0))
skipped += int(result.get("skipped", 0))
detail = {"groups": groups, "members": members, "skipped": skipped, "targeted": True}
else:
detail = self.service.refresh_all_chatrooms(
enable_weekly_digest=enable_weekly,
enable_monthly_digest=enable_monthly,
)
detail["targeted"] = False
return {
"success": True,
"summary": f"成员画像刷新完成: 群{detail.get('groups', 0)},成员{detail.get('members', 0)}",
"detail": detail,
}
except Exception as e:
return {"success": False, "summary": f"执行异常: {e}", "detail": {"error": str(e)}}