落地系统异常:大模型/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
+139
View File
@@ -2473,3 +2473,142 @@ def air_release_deal_blocked(work_order_no: str) -> str:
def air_release_need_lock(work_order_no: str) -> str:
no = (work_order_no or "").strip()
return f"工单{no}还没有有效锁舱,不能释放。"
# —— 系统异常(UC024):销售/群兜底与恢复;告警卡只给有权限的人 ——
TYPE_LLM = "大模型异常"
TYPE_TMS = "TMS异常"
TYPE_GROUP = "建群异常"
STEP_LLM_NO_TICKET = "llm_no_ticket"
STEP_LLM = "llm"
STEP_TMS_QUOTE = "tms_quote"
STEP_TMS_CABIN = "tms_cabin"
STEP_GROUP = "group"
SYS_EXC_LLM_FALLBACK = "大模型服务异常,IT排查中..."
SYS_EXC_TMS_FALLBACK = "TMS接口异常,IT运维排查中..."
SYS_EXC_RECOVERY_TMS = "TMS已恢复正常使用,感谢您的耐心等待。"
SYS_EXC_RECOVERY_LLM = "大模型已恢复正常使用,感谢您的耐心等待。"
SYS_EXC_RECOVERY_CABIN = "空运舱位接口已恢复正常使用,感谢您的耐心等待。"
SYS_EXC_RECOVERY_GROUP = "建群已恢复正常,感谢您的耐心等待。"
IMPACT_LLM_NO_TICKET = "尚未建单,不落后台工单"
IMPACT_LLM = "当前识别暂停,已有字段与工单状态保持不变"
IMPACT_TMS_QUOTE = "当前询价流程暂停,识别字段与原业务节点保持不变"
IMPACT_TMS_CABIN = "当前锁舱/释放暂停,工单状态保持不变"
IMPACT_GROUP = "当前建群/加人暂停,已建群不新建第二个群"
def system_exception_fallback(exception_type: str, *, names: list[str] | None = None) -> str:
"""判定系统异常后,给卡住的会话的兜底话术。"""
kind = (exception_type or "").strip()
if kind == TYPE_LLM:
return SYS_EXC_LLM_FALLBACK
if kind == TYPE_GROUP:
people = [str(x).strip() for x in (names or []) if str(x).strip()]
if not people:
return "无法添加同事,请联系管理员检查企业微信配置。"
joined = "、".join(people)
return f"无法添加 {joined} 同事,请联系管理员检查企业微信配置。"
return SYS_EXC_TMS_FALLBACK
def system_exception_recovery(step: str) -> str:
"""后台点重试成功后,先发这一句,再补没做完的事。"""
key = (step or "").strip()
if key == STEP_LLM or key == STEP_LLM_NO_TICKET:
return SYS_EXC_RECOVERY_LLM
if key == STEP_TMS_CABIN:
return SYS_EXC_RECOVERY_CABIN
if key == STEP_GROUP:
return SYS_EXC_RECOVERY_GROUP
return SYS_EXC_RECOVERY_TMS
def system_exception_impact(step: str) -> str:
"""告警卡「影响范围」,按卡住的步骤。"""
key = (step or "").strip()
if key == STEP_LLM_NO_TICKET:
return IMPACT_LLM_NO_TICKET
if key == STEP_LLM:
return IMPACT_LLM
if key == STEP_TMS_CABIN:
return IMPACT_TMS_CABIN
if key == STEP_GROUP:
return IMPACT_GROUP
return IMPACT_TMS_QUOTE
def system_exception_alert_payload(
*,
work_order_no: str,
exception_type: str,
service: str,
error_code: str,
step: str,
occurred_at: str,
test_prefix: bool = False,
) -> dict[str, Any]:
"""
系统异常通知卡:走询价消息服务,不走询价小助手。
五行对齐现网示例:异常类型、接口/服务、错误码、影响范围、发生时间。
"""
no = (work_order_no or "").strip() or "无"
title = "系统异常通知"
if test_prefix:
title = "[test] " + title
rows = [
{"keyname": "异常类型", "value": (exception_type or "").strip() or "-"},
{"keyname": "接口/服务", "value": (service or "").strip() or "-"},
{"keyname": "错误码", "value": (error_code or "").strip() or "-"},
{"keyname": "影响范围", "value": system_exception_impact(step)},
{"keyname": "发生时间", "value": (occurred_at or "").strip() or "-"},
]
from agent.config import get_settings
base = str(getattr(get_settings(), "public_base_url", "") or "").strip().rstrip("/")
action_url = base or "https://work.weixin.qq.com"
return {
"msgtype": "template_card",
"wecom_app": "notify",
"template_card": {
"card_type": "text_notice",
"source": {"desc": "询价机器人系统告警", "desc_color": 0},
"main_title": {
"title": title,
"desc": f"关联工单 {no}",
},
"horizontal_content_list": rows,
"card_action": {"type": 1, "url": action_url},
},
}
def system_exception_alert_text(
*,
work_order_no: str,
exception_type: str,
service: str,
error_code: str,
step: str,
occurred_at: str,
test_prefix: bool = False,
) -> str:
"""告警卡纯文本兜底(通道降级时仍能看懂)。"""
no = (work_order_no or "").strip() or "无"
head = "系统异常通知"
if test_prefix:
head = "[test] " + head
lines = [
"询价机器人系统告警",
head,
f"关联工单 {no}",
f"异常类型:{(exception_type or '').strip() or '-'}",
f"接口/服务:{(service or '').strip() or '-'}",
f"错误码:{(error_code or '').strip() or '-'}",
f"影响范围:{system_exception_impact(step)}",
f"发生时间:{(occurred_at or '').strip() or '-'}",
]
return "\n".join(lines)