落地并存测服全端:智能体 Graph/路由、后台切 8180、主账与部署脚本齐备,便于线上重发与验收。
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,128 @@
|
||||
"""
|
||||
入站分发壳:RouteDecision.intent → 唯一 handler。
|
||||
|
||||
本文件职责:维护意图→可调用对象表;dispatch_inbound 只查表调用。
|
||||
禁止:在本文件写补问/建单/TMS 业务;禁止一个函数处理全部卡片。
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
from typing import Callable, Optional
|
||||
|
||||
from agent.channel.wecom.models import InboundMessage
|
||||
from agent.handlers import abnormal, card_action, close_deal, continue_thread, new_inquiry
|
||||
from agent.handlers.echo_text import handle_echo_text
|
||||
from agent.routing.decision import RouteDecision
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# Handler 签名约定:只收 InboundMessage(出站/store 由 handler 自行取依赖)
|
||||
HandlerFn = Callable[[InboundMessage], None]
|
||||
|
||||
|
||||
def _noop(message: InboundMessage) -> None:
|
||||
"""忽略类意图:不做事。"""
|
||||
logger.info("dispatch.noop sender=%s msg=%s", message.sender_id, message.message_id)
|
||||
|
||||
|
||||
def _wrap_echo(message: InboundMessage) -> None:
|
||||
"""
|
||||
联调占位:文字意图暂走 echo(正式应换成 new_inquiry / Graph)。
|
||||
|
||||
框架接线用;不含字段抽取。
|
||||
"""
|
||||
from agent.channel.queue import get_message_store
|
||||
from agent.config import get_settings
|
||||
|
||||
settings = get_settings()
|
||||
handle_echo_text(
|
||||
message,
|
||||
get_message_store(),
|
||||
ytd_env=settings.ytd_env,
|
||||
reply_template=settings.wecom_callback_reply_text,
|
||||
)
|
||||
|
||||
|
||||
def _wrap_new(message: InboundMessage) -> None:
|
||||
new_inquiry.handle_new_inquiry(message)
|
||||
|
||||
|
||||
def _wrap_continue(message: InboundMessage) -> None:
|
||||
continue_thread.handle_continue_thread(message, thread_id="")
|
||||
|
||||
|
||||
def _wrap_card(message: InboundMessage) -> None:
|
||||
# 框架:卡片字段尚未从 payload 解析;空壳用默认
|
||||
card_action.handle_card_action(
|
||||
sender_id=message.sender_id,
|
||||
thread_id="",
|
||||
wait_version=0,
|
||||
action="unknown",
|
||||
payload={},
|
||||
)
|
||||
|
||||
|
||||
def _wrap_close(message: InboundMessage) -> None:
|
||||
close_deal.handle_close_deal(
|
||||
sender_id=message.sender_id,
|
||||
inquiry_no="",
|
||||
outcome="unknown",
|
||||
)
|
||||
|
||||
|
||||
def _wrap_abnormal(message: InboundMessage) -> None:
|
||||
abnormal.handle_abnormal(sender_id=message.sender_id, inquiry_no="", reason="dispatch")
|
||||
|
||||
|
||||
# 意图 → handler(空壳或联调 echo);扩展时只改表,不改 ChannelRuntime 分支森林
|
||||
HANDLER_REGISTRY: dict[str, HandlerFn] = {
|
||||
"echo_text": _wrap_echo,
|
||||
"ordinary_text_inquiry": _wrap_echo, # 联调:有回复;正式换业务 handler
|
||||
"ordinary_text_other": _wrap_echo,
|
||||
"attachment_inquiry": _wrap_new,
|
||||
"image_inquiry": _wrap_new,
|
||||
"multi_segment_transport": _wrap_new,
|
||||
"tms_read_only_quote": _wrap_continue,
|
||||
"new_inquiry": _wrap_new,
|
||||
"continue_thread": _wrap_continue,
|
||||
"card_action": _wrap_card,
|
||||
"close_deal": _wrap_close,
|
||||
"abnormal": _wrap_abnormal,
|
||||
"reject_no_sender": _noop,
|
||||
"ignore_empty": _noop,
|
||||
"stub_needs_model": _wrap_echo,
|
||||
}
|
||||
|
||||
|
||||
def resolve_handler(intent: str) -> Optional[HandlerFn]:
|
||||
"""查表;未知意图返回 None。"""
|
||||
return HANDLER_REGISTRY.get(intent)
|
||||
|
||||
|
||||
def dispatch_inbound(message: InboundMessage, decision: RouteDecision) -> str:
|
||||
"""
|
||||
按 RouteDecision 调用唯一 handler。
|
||||
|
||||
返回:实际调用的 intent 名,或 unknown_intent / skipped。
|
||||
副作用:仅 handler 内产生;本函数不做业务。
|
||||
"""
|
||||
if not message.has_sender() and decision.intent != "reject_no_sender":
|
||||
logger.warning("dispatch 拒绝:无 sender_id")
|
||||
HANDLER_REGISTRY["reject_no_sender"](message)
|
||||
return "reject_no_sender"
|
||||
|
||||
fn = resolve_handler(decision.intent)
|
||||
if fn is None:
|
||||
logger.warning("dispatch 未知意图 intent=%s → noop", decision.intent)
|
||||
_noop(message)
|
||||
return "unknown_intent"
|
||||
|
||||
logger.info(
|
||||
"dispatch intent=%s sender=%s msg=%s",
|
||||
decision.intent,
|
||||
message.sender_id,
|
||||
message.message_id,
|
||||
)
|
||||
fn(message)
|
||||
return decision.intent
|
||||
Reference in New Issue
Block a user