落地私聊空运询价与TMS报价回填,按后台模板出单。

查到价后把币种、单位、数量、单价、备注写入报价单,避免销售只看到光秃秃的金额。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-09-14 20:25:35 +08:00
co-authored by Cursor
parent cea3a6e51e
commit 99da1faf30
78 changed files with 8838 additions and 321 deletions
@@ -1,24 +1,62 @@
"""
意图:继续本单 / Graph resume(骨架)。
意图:继续历史工单。
正式:校验 thread_id + waitVersion 后 Worker 槽 resume;禁止在 HTTP 回调线程 invoke。
本文件职责:把 DeepSeek A 认出的续办意图交给流程,按工单号回到当时停点。
工单号优先用路由结论;模型漏填时再从原话机读 WO 号(不在这里判断意图)。
禁止:在本文件抽询价字段;禁止回调线程跑完整 LLM;禁止直连 TMS。
"""
from __future__ import annotations
import logging
from agent.channel.queue import get_message_store
from agent.channel.wecom.models import InboundMessage
from agent.policy import inquiry_copy as copy
from agent.policy.air_text_flow import get_air_text_flow
logger = logging.getLogger(__name__)
def handle_continue_thread(message: InboundMessage, *, thread_id: str = "") -> None:
"""骨架:仅记日志。"""
def handle_continue_thread(
message: InboundMessage,
*,
thread_id: str = "",
flow=None,
store=None,
) -> str:
"""
续办一张历史工单:回到该单当时节点的卡片/话术。
thread_id:RouteDecision 里的工单号。副作用:outbox 回复;读主账。
"""
if not message.has_sender():
return
logger.info(
"handler.continue_thread stub sender=%s thread_id=%s",
message.sender_id,
thread_id or "-",
logger.warning("continue_thread 拒绝:无 sender_id")
return "reject_no_sender"
msg_store = store or get_message_store()
engine = flow or get_air_text_flow()
replies: list[str] = []
def reply(text: str, extra: dict | None = None) -> None:
replies.append(text)
ok, info = msg_store.enqueue_outbound(
touser=message.sender_id,
content=text,
dedupe_key=f"cont:{message.message_id}:{len(replies)}",
payload=dict(extra or {}),
)
logger.info("continue_thread 出站 ok=%s info=%s", ok, info)
wo = (thread_id or "").strip() or copy.extract_work_order_no(message.content or "")
phase = engine.resume_historical(
sender_id=message.sender_id,
work_order_no=wo,
reply=reply,
)
logger.info(
"continue_thread phase=%s sender=%s wo=%s",
phase,
message.sender_id,
wo or "-",
)
return phase