Files
inquiry_robot/inquiry-agent/agent/handlers/group_collab.py
T

94 lines
2.8 KiB
Python

"""
意图:海运协同群里补协同字段。
本文件职责:群聊文字 → 只抽协同六字段 → 静默写主账。
禁止:回「已记下」;把闲聊/报价金额写成报价版本;改工单六态。
"""
from __future__ import annotations
import logging
from agent.channel.wecom.models import InboundMessage
from agent.llm.extract_text import extract_collab_fields
from agent.policy.sea_text_flow import get_sea_text_flow
from agent.schema.field_validate import SEA_COLLAB_FIELDS
logger = logging.getLogger(__name__)
def handle_group_collab(
message: InboundMessage,
*,
flow=None,
ledger=None,
) -> str:
"""
处理一条群聊文字。
必须能对上已绑定工单,且发言人是被拉进来的销售或产品。
识别到协同字段才写库;否则忽略。不回复。
"""
if (message.chat_type or "") != "group":
return "group_ignore"
if not message.has_sender():
return "reject_no_sender"
engine = flow or get_sea_text_flow()
book = ledger or engine.ledger
chat_id = (message.chat_id or "").strip()
if not chat_id:
return "group_ignore"
ticket = _find_ticket(book, chat_id)
if ticket is None:
return "group_ignore"
if not _sender_allowed(ticket, message.sender_id):
logger.info("group_collab 忽略非成员 sender=%s chat=%s", message.sender_id, chat_id)
return "group_ignore"
facts = extract_collab_fields(message.content or "")
if not facts:
return "group_ignore"
if isinstance(ticket, dict):
wo = str(ticket.get("work_order_no") or "")
else:
wo = str(getattr(ticket, "work_order_no", "") or "")
if not wo:
return "group_ignore"
engine.apply_collab_facts(
work_order_no=wo,
facts=facts,
sender_id=message.sender_id,
)
logger.info(
"group_collab 写入 wo=%s keys=%s sender=%s",
wo,
sorted(k for k in facts if k in SEA_COLLAB_FIELDS),
message.sender_id,
)
return "collab_field_saved"
def _find_ticket(book: object, chat_id: str):
finder = getattr(book, "find_by_collab_chat", None)
if callable(finder):
return finder(chat_id=chat_id)
return None
def _sender_allowed(ticket: object, sender_id: str) -> bool:
uid = (sender_id or "").strip()
if not uid:
return False
if isinstance(ticket, dict):
sales = str(ticket.get("sales_wecom_id") or ticket.get("salesWecomId") or "")
members = ticket.get("collab_member_ids") or ticket.get("memberIds") or []
else:
sales = str(getattr(ticket, "sales_wecom_id", "") or "")
members = list(getattr(ticket, "collab_member_ids", []) or [])
if uid == sales:
return True
return uid in {str(x) for x in members}