killer2 / werewolf /core /event_parser.py
JackWPP's picture
feat: 增强警长提取逻辑,支持从文本中解析警长名称并更新内存
adf80c9
import re
from typing import Dict, Optional
from agent_build_sdk.model.werewolf_model import (
AgentReq,
STATUS_DAY,
STATUS_HUNTER,
STATUS_HUNTER_RESULT,
STATUS_NIGHT,
STATUS_NIGHT_INFO,
STATUS_RESULT,
STATUS_SHERIFF_ELECTION,
STATUS_SHERIFF_PK,
STATUS_SHERIFF_SPEECH,
STATUS_SHERIFF_SPEECH_ORDER,
STATUS_SHERIFF_VOTE,
STATUS_SKILL_RESULT,
STATUS_VOTE,
STATUS_VOTE_RESULT,
STATUS_SHERIFF,
)
from core import ruleset
def _extract_sheriff_from_text(text: str) -> Optional[str]:
s = (text or "").strip()
if not s:
return None
if ruleset.SHERIFF_TEAR in s:
return None
patterns = [
r"警徽归属[::]?\s*([^\s,,。;;]+)",
r"警徽(?:移交|交给|传递|传给|给)[::]?\s*([^\s,,。;;]+)",
r"移交(?:警徽)?给[::]?\s*([^\s,,。;;]+)",
r"警长[::]\s*([^\s,,。;;]+)",
]
matches: list[tuple[int, str]] = []
for pat in patterns:
for m in re.finditer(pat, s):
matches.append((m.start(), (m.group(1) or "").strip()))
if not matches:
return None
_, name = sorted(matches, key=lambda x: x[0])[-1]
name = name.strip().strip("[]【】()()\"'“”‘’`").strip(",,。;;::")
if not name or name == ruleset.SHERIFF_TEAR:
return None
return name
def parse_event(req: AgentReq) -> Dict[str, str]:
return {
"status": req.status or "",
"name": req.name or "",
"message": req.message or "",
"round": str(req.round) if req.round is not None else "",
"role": req.role or "",
}
def event_to_fact(req: AgentReq) -> Optional[Dict[str, str]]:
status = req.status or ""
round_no = str(req.round) if req.round is not None else ""
if status == STATUS_VOTE:
return {
"type": "vote",
"round": round_no,
"voter": req.name or "",
"target": req.message or "",
}
if status == STATUS_VOTE_RESULT:
return {
"type": "vote_result",
"round": round_no,
"out": (req.name or req.message or ""),
}
if status == STATUS_NIGHT_INFO:
return {
"type": "night_info",
"round": round_no,
"message": req.message or "",
}
if status == STATUS_NIGHT:
return {
"type": "night",
"round": round_no,
"message": req.message or "",
}
if status == STATUS_DAY:
return {
"type": "day",
"round": round_no,
"message": req.message or "",
}
if status == STATUS_SKILL_RESULT:
return {
"type": "skill_result",
"round": round_no,
"name": req.name or "",
"message": req.message or "",
}
if status == STATUS_HUNTER:
return {
"type": "hunter",
"round": round_no,
"name": req.name or "",
"message": req.message or "",
}
if status == STATUS_HUNTER_RESULT:
return {
"type": "hunter_result",
"round": round_no,
"name": req.name or "",
"target": req.message or "",
}
if status == STATUS_RESULT:
return {
"type": "result",
"round": round_no,
"message": req.message or "",
}
if status == STATUS_SHERIFF_ELECTION:
return {
"type": "sheriff_election",
"round": round_no,
"message": req.message or "",
}
if status == STATUS_SHERIFF_SPEECH:
return {
"type": "sheriff_speech",
"round": round_no,
"name": req.name or "",
"message": req.message or "",
}
if status == STATUS_SHERIFF_PK:
return {
"type": "sheriff_pk",
"round": round_no,
"name": req.name or "",
"message": req.message or "",
}
if status == STATUS_SHERIFF_VOTE:
return {
"type": "sheriff_vote",
"round": round_no,
"name": req.name or "",
"target": req.message or "",
}
if status == STATUS_SHERIFF_SPEECH_ORDER:
return {
"type": "sheriff_speech_order",
"round": round_no,
"message": req.message or "",
}
if status == STATUS_SHERIFF:
sheriff_name = req.name or _extract_sheriff_from_text(req.message or "")
if not sheriff_name:
return None
return {
"type": "sheriff",
"round": round_no,
"name": sheriff_name,
}
return None