重启后仍能跳过协同出方案,未成交可同一句带原因;海陆有价卡改为直接生成报价单。
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -18,6 +18,54 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
EnqueueFn = Callable[..., tuple[bool, str]]
|
||||
|
||||
# 成交跟进里先认未成交,避免被「成交」误伤。
|
||||
_LOST_MARKERS = ("未成交", "没成交", "没有成交", "没做成", "黄了")
|
||||
_QUESTION_TAILS = frozenset({"吗", "呢", "吧", "啊", "呀", "嘛", "?", "?"})
|
||||
_KEEP_REASON_AS_IS = frozenset({"原因不明", "原因不详", "理由不明", "理由不详"})
|
||||
|
||||
|
||||
def harvest_inline_lost_reason(text: str) -> str:
|
||||
"""
|
||||
从「未成交,原因客户不想要了」这类一句里抽出原因。
|
||||
|
||||
只写未成交、问句尾巴(吗/呢)不当原因。原因不明整句保留。
|
||||
调用:成交跟进私聊/群聊;不在回调线程跑。
|
||||
"""
|
||||
raw = (text or "").strip()
|
||||
if not raw:
|
||||
return ""
|
||||
compact = raw.replace(" ", "")
|
||||
marker = ""
|
||||
at = -1
|
||||
for token in _LOST_MARKERS:
|
||||
hit = compact.find(token)
|
||||
if hit < 0:
|
||||
continue
|
||||
if at < 0 or hit < at:
|
||||
at = hit
|
||||
marker = token
|
||||
if at < 0 or not marker:
|
||||
return ""
|
||||
rest = compact[at + len(marker) :].strip()
|
||||
rest = rest.lstrip(",,。.;;::、-/—")
|
||||
if rest in _KEEP_REASON_AS_IS:
|
||||
return rest
|
||||
for label in ("未成交原因是", "未成交原因", "原因是", "理由是", "原因", "理由"):
|
||||
if rest.startswith(label):
|
||||
rest = rest[len(label) :].lstrip(",,。.;;::、-/— ")
|
||||
break
|
||||
if rest in _QUESTION_TAILS:
|
||||
return ""
|
||||
return rest.strip()
|
||||
|
||||
|
||||
def looks_like_lost_outcome(text: str) -> bool:
|
||||
"""成交跟进阶段:这句话是在说未成交。"""
|
||||
blob = (text or "").replace(" ", "")
|
||||
if not blob:
|
||||
return False
|
||||
return any(token in blob for token in _LOST_MARKERS)
|
||||
|
||||
|
||||
def notify_app_ready() -> bool:
|
||||
"""询价消息服务已配 AgentId+Secret 才推。空则只成交不推。"""
|
||||
@@ -65,12 +113,13 @@ def finish_deal_outcome(
|
||||
sales_name: str = "",
|
||||
enqueue: Optional[EnqueueFn] = None,
|
||||
notify_ready: Optional[bool] = None,
|
||||
lost_reason: str = "",
|
||||
) -> dict[str, Any]:
|
||||
"""
|
||||
先入主账,再按结果推人或排再问。
|
||||
|
||||
返回 ok / phase / notify_summary。phase:
|
||||
已成交 done;未成交 wait_lost_reason;协商中 wait_deal。
|
||||
已成交 done;未成交无原因 wait_lost_reason;未成交已带原因 done;协商中 wait_deal。
|
||||
"""
|
||||
no = (work_order_no or "").strip()
|
||||
status = (outcome or "").strip()
|
||||
@@ -135,7 +184,15 @@ def finish_deal_outcome(
|
||||
return {"ok": False, "error": result.get("error") or "transition_failed", "phase": "ledger_fail"}
|
||||
from agent.policy.event_exception import WAIT_LOST_REASON, clear_wait, start_wait
|
||||
|
||||
if status == "未成交":
|
||||
inline_reason = (lost_reason or "").strip()
|
||||
if status == "未成交" and inline_reason:
|
||||
captured = capture_lost_reason(ledger=ledger, work_order_no=no, reason=inline_reason)
|
||||
if captured.get("ok"):
|
||||
phase = "done"
|
||||
else:
|
||||
phase = "wait_lost_reason"
|
||||
start_wait(ledger, work_order_no=no, wait_kind=WAIT_LOST_REASON)
|
||||
elif status == "未成交":
|
||||
phase = "wait_lost_reason"
|
||||
start_wait(ledger, work_order_no=no, wait_kind=WAIT_LOST_REASON)
|
||||
elif status == "协商中":
|
||||
|
||||
Reference in New Issue
Block a user