落地多段联运私聊:齐了才建单拉群,附件只收格子值,核对改正不再整单重开。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-09-23 15:08:15 +08:00
co-authored by Cursor
parent 6e3e09a316
commit 2334524bb8
30 changed files with 4033 additions and 40 deletions
+42 -3
View File
@@ -23,9 +23,34 @@ from agent.policy.image_wave import WaveKV
WAIT_TTL_SECONDS = 30 * 60
# 已开始认的波次短协调:超时后当新开,不当六态。
_WAVE_TTL_SEC = 2 * 3600
# 报价单整理后常是空的,文件名仍能标运输方式。
_LAND_NAME_HINTS = ("陆运", "零担", "拼车", "整车", "中港", "城配")
_SEA_NAME_HINTS = ("海运",)
_AIR_NAME_HINTS = ("空运",)
logger = logging.getLogger(__name__)
def infer_attach_mode_word(filename: str) -> str:
"""
从附件文件名读运输方式。只认一种才返回「陆运/海运/空运」。
陆运报价单被千问整理成空时,仍要靠文件名留下一段,避免口播只剩海运。
"""
name = (filename or "").strip()
if not name:
return ""
hits: list[str] = []
if any(word in name for word in _LAND_NAME_HINTS):
hits.append("陆运")
if any(word in name for word in _SEA_NAME_HINTS):
hits.append("海运")
if any(word in name for word in _AIR_NAME_HINTS):
hits.append("空运")
if len(hits) == 1:
return hits[0]
return ""
@dataclass
class AttachMaterial:
"""一份按到达/上传顺序记下的材料。text 在识别完成后才填。"""
@@ -270,7 +295,12 @@ class AttachWaveBook:
self._persist(sid)
def compose_oral(self, sender_id: str) -> str:
"""开口字 + 按材料顺序的原文 + 后到的字。"""
"""
开口字 + 按材料顺序的原文 + 后到的字。
文件名能点名运输方式时,即使该份整理结果为空,也写「段N:陆运」这类标,
好让多段切段看见陆运+海运,而不是只走海运单聊。
"""
sid = (sender_id or "").strip()
with self._lock:
self._hydrate(sid)
@@ -280,9 +310,18 @@ class AttachWaveBook:
parts: list[str] = []
if wave.precede_text.strip():
parts.append(wave.precede_text.strip())
seg = 0
for row in wave.materials:
if row.text.strip():
parts.append(row.text.strip())
body = (row.text or "").strip()
word = infer_attach_mode_word(row.filename)
if word:
seg += 1
block = f"段{seg}:{word}"
if body:
block = f"{block}\n{body}"
parts.append(block)
elif body:
parts.append(body)
if wave.follow_text.strip():
parts.append(wave.follow_text.strip())
return "\n".join(parts)