落地系统异常:大模型/TMS/建群故障停住本单并告警,后台可重试失败步骤。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-09-21 14:01:49 +08:00
co-authored by Cursor
parent a5e73c01ae
commit 4381966c4e
26 changed files with 2098 additions and 72 deletions
+76 -5
View File
@@ -113,6 +113,17 @@ class SeaTextInquiryFlow(AirTextInquiryFlow):
allow_b=allow_b,
chat_fn=chat_fn,
)
from agent.policy.system_exception import handle_extract_tech_fail
llm_phase = handle_extract_tech_fail(
snap=snap,
ledger=self._ledger,
reply=reply,
sender_id=sender_id,
sess=sess,
)
if llm_phase:
return llm_phase
mode = (snap.get("business_line") or "").upper()
facts = dict(snap.get("facts") or {})
if sess and sess.phase in {"clarify", "need_mode"}:
@@ -263,7 +274,14 @@ class SeaTextInquiryFlow(AirTextInquiryFlow):
self._wait_inquiry_sent(str(out_id), work_order_no=no)
tms_facts = dict(assemble_sea_query(facts).get("tms_facts") or facts)
tms = self._ledger.query_tms(work_order_no=no, facts=tms_facts, business_line="SEA")
from agent.policy.system_exception import (
confirm_tms_quote_if_tech,
query_tms_resilient,
)
tms = query_tms_resilient(
self._ledger, work_order_no=no, facts=tms_facts, business_line="SEA"
)
sess = FlowSession(
sender_id=sender_id,
thread_id=sender_id,
@@ -276,6 +294,16 @@ class SeaTextInquiryFlow(AirTextInquiryFlow):
wait_version=1,
)
if not tms.get("ok"):
if confirm_tms_quote_if_tech(
ledger=self._ledger,
reply=reply,
work_order_no=no,
tms=tms,
sender_id=sender_id,
ticket_status="询价中",
):
self.drop_current_bookmark(sender_id)
return "system_exception"
if tms.get("classification") == "TMS_QUERY_INCOMPLETE":
logger.warning("tms.query 未出站 wo=%s class=%s", no, tms.get("classification"))
reply("TMS 查询失败,请稍后重试。工单已创建:" + no)
@@ -549,9 +577,29 @@ class SeaTextInquiryFlow(AirTextInquiryFlow):
userids.append(uid)
client = self.group_client()
created = client.create_group(name=no, userids=userids) or {}
from agent.policy.system_exception import call_with_retries, confirm_group_if_tech
created = call_with_retries(
lambda: client.create_group(name=no, userids=userids) or {},
is_ok=lambda x: bool((x or {}).get("ok") and (x or {}).get("chat_id")),
)
if not created.get("ok") or not created.get("chat_id"):
reply(copy.sea_group_create_fail(reason=str(created.get("error") or "")))
getter = getattr(self._ledger, "get_ticket", None)
st = ""
if callable(getter):
tic = getter(work_order_no=no)
st = str(getattr(tic, "status", "") or (tic.get("status") if isinstance(tic, dict) else "") or "")
confirm_group_if_tech(
ledger=self._ledger,
reply=reply,
work_order_no=no,
sender_id=sess.sender_id,
missing_names=product_names,
reason=str(created.get("error") or "企微建群失败"),
error_code=str(created.get("error") or "GROUP_CREATE"),
ticket_status=st,
extra={"userids": userids, "product_names": product_names},
)
return sess.phase or "wait_collab"
chat_id = str(created.get("chat_id") or "").strip()
@@ -707,9 +755,32 @@ class SeaTextInquiryFlow(AirTextInquiryFlow):
if uid not in userids:
userids.append(uid)
client = self.group_client()
created = client.create_group(name=display_no, userids=userids) or {}
from agent.policy.system_exception import call_with_retries, confirm_group_if_tech
created = call_with_retries(
lambda: client.create_group(name=display_no, userids=userids) or {},
is_ok=lambda x: bool((x or {}).get("ok") and (x or {}).get("chat_id")),
)
if not created.get("ok") or not created.get("chat_id"):
reply(copy.sea_group_create_fail(reason=str(created.get("error") or "")))
real = (sess.work_order_no or "").strip()
mark_no = real if real.upper().startswith("WO") else ""
st = ""
if mark_no:
getter = getattr(self._ledger, "get_ticket", None)
if callable(getter):
tic = getter(work_order_no=mark_no)
st = str(getattr(tic, "status", "") or (tic.get("status") if isinstance(tic, dict) else "") or "")
confirm_group_if_tech(
ledger=self._ledger,
reply=reply,
work_order_no=mark_no,
sender_id=sess.sender_id,
missing_names=product_names,
reason=str(created.get("error") or "企微建群失败"),
error_code=str(created.get("error") or "GROUP_CREATE"),
ticket_status=st,
extra={"userids": userids, "product_names": product_names, "display_no": display_no},
)
return sess.phase or "handoff_offer"
chat_id = str(created.get("chat_id") or "").strip()
brief = copy.handoff_group_brief(