refactor: extract order helpers and stabilize first-image ack replies
This commit is contained in:
@@ -3,6 +3,7 @@ from __future__ import annotations
|
|||||||
import asyncio
|
import asyncio
|
||||||
from typing import TYPE_CHECKING, Optional
|
from typing import TYPE_CHECKING, Optional
|
||||||
from core.post_ops import record_deal_success
|
from core.post_ops import record_deal_success
|
||||||
|
from core.order_helpers import parse_order_info
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from core.pydantic_ai_agent import AgentResponse, ConversationState, CustomerMessage, CustomerServiceAgent
|
from core.pydantic_ai_agent import AgentResponse, ConversationState, CustomerMessage, CustomerServiceAgent
|
||||||
@@ -22,7 +23,7 @@ async def handle_order_notification(
|
|||||||
|
|
||||||
_, order_block = agent._split_customer_text(message.msg)
|
_, order_block = agent._split_customer_text(message.msg)
|
||||||
customer_text, _ = agent._split_customer_text(message.msg)
|
customer_text, _ = agent._split_customer_text(message.msg)
|
||||||
order = agent._parse_order_info(order_block or message.msg)
|
order = parse_order_info(order_block or message.msg)
|
||||||
pay_status = order.get("pay_status", "")
|
pay_status = order.get("pay_status", "")
|
||||||
order_status = order.get("order_status", "")
|
order_status = order.get("order_status", "")
|
||||||
|
|
||||||
|
|||||||
38
core/order_helpers.py
Normal file
38
core/order_helpers.py
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import re
|
||||||
|
from typing import Dict
|
||||||
|
|
||||||
|
|
||||||
|
def parse_order_info(msg: str) -> Dict[str, str]:
|
||||||
|
"""从系统订单消息中提取字段。"""
|
||||||
|
info: Dict[str, str] = {}
|
||||||
|
m = re.search(r"订单号[::]\s*(\d+)", msg or "")
|
||||||
|
if m:
|
||||||
|
info["order_id"] = m.group(1)
|
||||||
|
m = re.search(r"订单状态[::]\s*([^\s\[]+)", msg or "")
|
||||||
|
if m:
|
||||||
|
info["order_status"] = m.group(1).strip()
|
||||||
|
m = re.search(r"\[状态[::]\s*([^\]]+)\]", msg or "")
|
||||||
|
if m:
|
||||||
|
info["pay_status"] = m.group(1).strip()
|
||||||
|
m = re.search(r"金额[::]\s*([\d.]+)元", msg or "")
|
||||||
|
if m:
|
||||||
|
info["amount"] = m.group(1)
|
||||||
|
m = re.search(r"数量[::]\s*(\d+)", msg or "")
|
||||||
|
if m:
|
||||||
|
info["quantity"] = m.group(1)
|
||||||
|
m = re.search(r"(\d{4}-\d{1,2}-\d{1,2}\s+\d{1,2}:\d{2}:\d{2})", msg or "")
|
||||||
|
if m:
|
||||||
|
info["order_time"] = m.group(1).strip()
|
||||||
|
m = re.search(r"买家备注[::]\s*([^\n]+)", msg or "")
|
||||||
|
if m and m.group(1).strip():
|
||||||
|
info["buyer_note"] = m.group(1).strip()
|
||||||
|
return info
|
||||||
|
|
||||||
|
|
||||||
|
def order_instruction(pay_status: str, order_status: str) -> str:
|
||||||
|
paid_keywords = ["等待发货", "已付款", "付款成功", "买家已付款"]
|
||||||
|
if any(kw in (pay_status or "") or kw in (order_status or "") for kw in paid_keywords):
|
||||||
|
return "【已付款-必须回复】客户已付款,立刻自然回复确认收款并告知马上安排。"
|
||||||
|
return "【仅系统通知-无需回复客户】这是系统订单通知,不需要回复客户任何内容,直接跳过。"
|
||||||
@@ -31,6 +31,7 @@ from core.order_flow import handle_order_notification
|
|||||||
from core.ai_reply_flow import execute_ai_turn
|
from core.ai_reply_flow import execute_ai_turn
|
||||||
from core.reply_finalize_flow import finalize_ai_reply
|
from core.reply_finalize_flow import finalize_ai_reply
|
||||||
from core.prompt_flow import build_prompt_bundle
|
from core.prompt_flow import build_prompt_bundle
|
||||||
|
from core.order_helpers import parse_order_info, order_instruction as build_order_instruction
|
||||||
|
|
||||||
load_dotenv()
|
load_dotenv()
|
||||||
|
|
||||||
@@ -443,12 +444,12 @@ class CustomerServiceAgent:
|
|||||||
if scene == "collect_ack" and len(state.pending_image_urls) == 1:
|
if scene == "collect_ack" and len(state.pending_image_urls) == 1:
|
||||||
first_ack = [
|
first_ack = [
|
||||||
"收到了,我先看一下哈,稍等哈",
|
"收到了,我先看一下哈,稍等哈",
|
||||||
"这张我收到了,我先看下,等我一下哈",
|
"这张我收到了,我先看下,稍等我一下哈",
|
||||||
"收到这张了,我先过一眼,稍等哈",
|
"收到这张了,我先过一眼,稍等哈",
|
||||||
"我先看这张哈,稍等我一下",
|
"我先看这张哈,稍等我一下",
|
||||||
"图我收到了,我先看一眼,马上回你哈",
|
"图我收到了,我先看一眼,稍等我回你哈",
|
||||||
"这张先记上了,我先看下细节,稍等哈",
|
"这张先记上了,我先看下细节,稍等哈",
|
||||||
"收到哈,我先过一遍这张,等我会儿",
|
"收到哈,我先过一遍这张,稍等我会儿",
|
||||||
"我先看这张效果,稍等一下哈",
|
"我先看这张效果,稍等一下哈",
|
||||||
"图到了,我先看下清晰度,稍等哈",
|
"图到了,我先看下清晰度,稍等哈",
|
||||||
"这张我先看着,稍等我一下就回你",
|
"这张我先看着,稍等我一下就回你",
|
||||||
@@ -914,7 +915,7 @@ class CustomerServiceAgent:
|
|||||||
@self.agent_order.tool
|
@self.agent_order.tool
|
||||||
async def handle_order(ctx: RunContext[AgentDeps], raw_msg: str = "") -> str:
|
async def handle_order(ctx: RunContext[AgentDeps], raw_msg: str = "") -> str:
|
||||||
try:
|
try:
|
||||||
info = self._parse_order_info(raw_msg or "")
|
info = parse_order_info(raw_msg or "")
|
||||||
paid_kw = ["等待发货", "已付款", "付款成功", "买家已付款"]
|
paid_kw = ["等待发货", "已付款", "付款成功", "买家已付款"]
|
||||||
if any(k in (info.get("pay_status", "") or "") for k in paid_kw) or any(k in (info.get("order_status", "") or "") for k in paid_kw):
|
if any(k in (info.get("pay_status", "") or "") for k in paid_kw) or any(k in (info.get("order_status", "") or "") for k in paid_kw):
|
||||||
return "已安排,稍后发你"
|
return "已安排,稍后发你"
|
||||||
@@ -1900,59 +1901,6 @@ class CustomerServiceAgent:
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"[Agent] 订单金额核查失败: {e}")
|
print(f"[Agent] 订单金额核查失败: {e}")
|
||||||
|
|
||||||
def _parse_order_info(self, msg: str) -> dict:
|
|
||||||
"""从系统订单消息中提取所有字段"""
|
|
||||||
import re
|
|
||||||
info = {}
|
|
||||||
|
|
||||||
m = re.search(r'订单号[::]\s*(\d+)', msg)
|
|
||||||
if m:
|
|
||||||
info['order_id'] = m.group(1)
|
|
||||||
|
|
||||||
# 订单大状态(新订单/交易成功/交易关闭等)
|
|
||||||
m = re.search(r'订单状态[::]\s*([^\s\[]+)', msg)
|
|
||||||
if m:
|
|
||||||
info['order_status'] = m.group(1).strip()
|
|
||||||
|
|
||||||
# 支付细状态(等待买家付款/等待发货/交易完成等)
|
|
||||||
m = re.search(r'\[状态[::]\s*([^\]]+)\]', msg)
|
|
||||||
if m:
|
|
||||||
info['pay_status'] = m.group(1).strip()
|
|
||||||
|
|
||||||
# 金额
|
|
||||||
m = re.search(r'金额[::]\s*([\d.]+)元', msg)
|
|
||||||
if m:
|
|
||||||
info['amount'] = m.group(1)
|
|
||||||
|
|
||||||
# 数量
|
|
||||||
m = re.search(r'数量[::]\s*(\d+)', msg)
|
|
||||||
if m:
|
|
||||||
info['quantity'] = m.group(1)
|
|
||||||
|
|
||||||
# 时间(格式:2026-2-24 19:52:52)
|
|
||||||
m = re.search(r'(\d{4}-\d{1,2}-\d{1,2}\s+\d{1,2}:\d{2}:\d{2})', msg)
|
|
||||||
if m:
|
|
||||||
info['order_time'] = m.group(1).strip()
|
|
||||||
|
|
||||||
# 买家备注
|
|
||||||
m = re.search(r'买家备注[::]\s*([^\n]+)', msg)
|
|
||||||
if m and m.group(1).strip():
|
|
||||||
info['buyer_note'] = m.group(1).strip()
|
|
||||||
|
|
||||||
return info
|
|
||||||
|
|
||||||
def _get_order_instruction(self, pay_status: str, order_status: str) -> str:
|
|
||||||
"""
|
|
||||||
根据订单状态生成 AI 指令。
|
|
||||||
只有「已付款」才需要回复客户,其他状态一律静默。
|
|
||||||
"""
|
|
||||||
paid_keywords = ["等待发货", "已付款", "付款成功", "买家已付款"]
|
|
||||||
if any(kw in pay_status or kw in order_status for kw in paid_keywords):
|
|
||||||
return "【已付款-必须回复】客户已付款,立刻自然回复确认收款并告知马上安排。"
|
|
||||||
else:
|
|
||||||
# 所有其他状态(待付款、交易完成、关闭等)静默处理
|
|
||||||
return "【仅系统通知-无需回复客户】这是系统订单通知,不需要回复客户任何内容,直接跳过。"
|
|
||||||
|
|
||||||
def _extract_image_url(self, msg: str) -> str:
|
def _extract_image_url(self, msg: str) -> str:
|
||||||
"""从消息中提取图片URL,兼容纯URL和 text#*#url 两种格式"""
|
"""从消息中提取图片URL,兼容纯URL和 text#*#url 两种格式"""
|
||||||
urls = self._extract_image_urls(msg)
|
urls = self._extract_image_urls(msg)
|
||||||
@@ -2653,7 +2601,7 @@ class CustomerServiceAgent:
|
|||||||
has_order = bool(order_block)
|
has_order = bool(order_block)
|
||||||
|
|
||||||
if has_order:
|
if has_order:
|
||||||
order = self._parse_order_info(order_block)
|
order = parse_order_info(order_block)
|
||||||
if order.get('order_id'):
|
if order.get('order_id'):
|
||||||
state.last_order_id = order['order_id']
|
state.last_order_id = order['order_id']
|
||||||
stage_info += f"\n【订单号】{order['order_id']}"
|
stage_info += f"\n【订单号】{order['order_id']}"
|
||||||
@@ -2707,7 +2655,7 @@ class CustomerServiceAgent:
|
|||||||
order_paid = False
|
order_paid = False
|
||||||
order_unpaid = False
|
order_unpaid = False
|
||||||
if has_order:
|
if has_order:
|
||||||
order = self._parse_order_info(order_block)
|
order = parse_order_info(order_block)
|
||||||
paid_kws = ["等待发货", "已付款", "付款成功", "买家已付款"]
|
paid_kws = ["等待发货", "已付款", "付款成功", "买家已付款"]
|
||||||
unpaid_kws = ["等待买家付款", "待付款", "未付款"]
|
unpaid_kws = ["等待买家付款", "待付款", "未付款"]
|
||||||
ps = order.get('pay_status', '')
|
ps = order.get('pay_status', '')
|
||||||
@@ -2774,8 +2722,8 @@ class CustomerServiceAgent:
|
|||||||
|
|
||||||
# ── 附加订单信息(不覆盖客户问题的优先级)──
|
# ── 附加订单信息(不覆盖客户问题的优先级)──
|
||||||
if has_order:
|
if has_order:
|
||||||
order = self._parse_order_info(order_block)
|
order = parse_order_info(order_block)
|
||||||
order_instruction = self._get_order_instruction(
|
order_instruction = build_order_instruction(
|
||||||
order.get('pay_status', ''),
|
order.get('pay_status', ''),
|
||||||
order.get('order_status', '')
|
order.get('order_status', '')
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user