私聊建单前拦住枪支弹药爆炸物和毒品,避免真家伙进入报价。
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -43,7 +43,7 @@ from agent.schema.land_options import (
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# 只有补问/核对还能续同一张多段草稿。已出号的拉群停点不能拦住新询价。
|
||||
_FRONT = frozenset({"clarify", "wait_confirm"})
|
||||
_FRONT = frozenset({"clarify", "wait_confirm", "sensitive_block"})
|
||||
|
||||
|
||||
class MultiTextInquiryFlow:
|
||||
@@ -170,6 +170,52 @@ class MultiTextInquiryFlow:
|
||||
reply("多段询价请先把各段需求发齐并回复确定。需要人来接管时,请在工单创建后再说。")
|
||||
return "multi_handoff_later"
|
||||
|
||||
def _gate_sensitive(
|
||||
self,
|
||||
*,
|
||||
sender_id: str,
|
||||
text: str,
|
||||
reply: ReplyFn,
|
||||
segments: list[Segment],
|
||||
sess: Optional[FlowSession],
|
||||
immutable: str,
|
||||
) -> Optional[str]:
|
||||
"""
|
||||
多段私聊建单前的违禁品拦截。
|
||||
|
||||
已有工单号的旧会话不把违禁原话带进新的一段。没命中则把品名改口写回各段。
|
||||
命中只回一句,不补问、不建单。
|
||||
"""
|
||||
from agent.policy.sensitive_cargo import BLOCK_REPLY, judge
|
||||
|
||||
facts: dict[str, str] = {}
|
||||
for seg in segments:
|
||||
for key, value in (seg.facts or {}).items():
|
||||
if str(value or "").strip():
|
||||
facts[str(key)] = str(value)
|
||||
use_old = sess is not None and not (sess.work_order_no or "").strip()
|
||||
blocked, new_hold, edits = judge(
|
||||
text=text,
|
||||
facts=facts,
|
||||
hold=str(sess.sensitive_hold or "") if use_old else "",
|
||||
)
|
||||
for seg in segments:
|
||||
for key, value in edits.items():
|
||||
seg.facts[key] = value
|
||||
if not blocked:
|
||||
if use_old and sess is not None:
|
||||
sess.sensitive_hold = new_hold
|
||||
if edits:
|
||||
self._put_segments(sess, segments)
|
||||
self._save(sess)
|
||||
return None
|
||||
draft = self._draft(sender_id, segments, phase="sensitive_block", immutable=immutable or text)
|
||||
draft.sensitive_hold = new_hold
|
||||
self._save(draft)
|
||||
reply(BLOCK_REPLY)
|
||||
logger.info("multi.sensitive_block sender=%s", sender_id)
|
||||
return "sensitive_block"
|
||||
|
||||
def on_text(
|
||||
self,
|
||||
*,
|
||||
@@ -196,6 +242,19 @@ class MultiTextInquiryFlow:
|
||||
sess = self.session_of(sid)
|
||||
if sess and self.match_button(raw, sess):
|
||||
return self._pull_group(sess, reply)
|
||||
if sess and (sess.phase or "") == "sensitive_block" and not (sess.work_order_no or "").strip():
|
||||
refused = self._gate_sensitive(
|
||||
sender_id=sid,
|
||||
text=raw,
|
||||
reply=reply,
|
||||
segments=self._segments(sess),
|
||||
sess=sess,
|
||||
immutable=sess.immutable_text or raw,
|
||||
)
|
||||
if refused:
|
||||
return refused
|
||||
sess.phase = "clarify"
|
||||
self._save(sess)
|
||||
verdict = classify_multi_text(raw)
|
||||
if verdict == "same_mode":
|
||||
reply(copy.MULTI_SAME_MODE)
|
||||
@@ -276,7 +335,28 @@ class MultiTextInquiryFlow:
|
||||
附件口播经常没有「起运港:」这种标签,要按段走和单聊一样的抽取,
|
||||
不能只认标签行,否则会整段待补充。
|
||||
"""
|
||||
current = self.session_of(sender_id)
|
||||
refused = self._gate_sensitive(
|
||||
sender_id=sender_id,
|
||||
text=immutable,
|
||||
reply=reply,
|
||||
segments=list(segments),
|
||||
sess=current if current and not (current.work_order_no or "").strip() else None,
|
||||
immutable=immutable,
|
||||
)
|
||||
if refused:
|
||||
return refused
|
||||
filled = self._enrich_segments(segments, allow_b=allow_b, chat_fn=chat_fn)
|
||||
refused = self._gate_sensitive(
|
||||
sender_id=sender_id,
|
||||
text="",
|
||||
reply=reply,
|
||||
segments=filled,
|
||||
sess=self.session_of(sender_id),
|
||||
immutable=immutable,
|
||||
)
|
||||
if refused:
|
||||
return refused
|
||||
ready, updated, gaps = refresh_segments(filled)
|
||||
if not ready:
|
||||
self._reply_gaps(updated, gaps, reply)
|
||||
@@ -358,6 +438,16 @@ class MultiTextInquiryFlow:
|
||||
|
||||
口语补句走单聊同一套抽取,不在这里猜「广州-深圳」。
|
||||
"""
|
||||
refused = self._gate_sensitive(
|
||||
sender_id=sess.sender_id,
|
||||
text=text,
|
||||
reply=reply,
|
||||
segments=self._segments(sess),
|
||||
sess=sess,
|
||||
immutable=sess.immutable_text or text,
|
||||
)
|
||||
if refused:
|
||||
return refused
|
||||
from agent.llm.extract_text import extract_inquiry_snapshot
|
||||
from agent.policy.system_exception import handle_extract_tech_fail
|
||||
|
||||
@@ -407,6 +497,16 @@ class MultiTextInquiryFlow:
|
||||
def _create_ticket(self, sess: FlowSession, reply: ReplyFn) -> str:
|
||||
"""回复确定后建一张 MULTI 工单。含空运只给手动拉群提示,不含空运出拉群卡。"""
|
||||
segments = self._segments(sess)
|
||||
refused = self._gate_sensitive(
|
||||
sender_id=sess.sender_id,
|
||||
text="",
|
||||
reply=reply,
|
||||
segments=segments,
|
||||
sess=sess,
|
||||
immutable=sess.immutable_text,
|
||||
)
|
||||
if refused:
|
||||
return refused
|
||||
ready, updated, gaps = refresh_segments(segments)
|
||||
if not ready:
|
||||
self._reply_gaps(updated, gaps, reply)
|
||||
|
||||
Reference in New Issue
Block a user