from __future__ import annotations import os import asyncio from typing import Any import requests from .observability import activity_event DEFAULT_TRANSFER_GROUP = os.getenv("TRANSFER_GROUP_ID", "20252916034").strip() or "20252916034" DEFAULT_TRANSFER_ASSIGNEE = os.getenv("TRANSFER_ASSIGNED_TO", "").strip() DISPATCH_BASE_URL = os.getenv("DISPATCH_BASE_URL", "http://1.12.50.92:8006").strip().rstrip("/") DISPATCH_API_KEY = os.getenv("DISPATCH_API_KEY", "tuhui_dispatch_key_2026").strip() DISPATCH_TIMEOUT_SECONDS = float(os.getenv("DISPATCH_TIMEOUT_SECONDS", "5")) def _dispatch_assign_once() -> dict[str, Any]: if not DISPATCH_BASE_URL or not DISPATCH_API_KEY: return {"success": False, "reason": "dispatch_config_missing"} try: resp = requests.get( f"{DISPATCH_BASE_URL}/assign", headers={"X-API-Key": DISPATCH_API_KEY}, timeout=DISPATCH_TIMEOUT_SECONDS, ) if resp.status_code != 200: return {"success": False, "reason": f"http_{resp.status_code}"} data = resp.json() if resp.text else {} return { "success": bool(data.get("success", False)), "task_id": str(data.get("task_id", "") or ""), "assigned_to": str(data.get("assigned_to", "") or ""), "online_count": int(data.get("online_count", 0) or 0), "raw": data, } except Exception as e: return {"success": False, "reason": str(e)} async def transfer_to_human_flow(client, data: dict[str, Any], transfer_msg: str = "", trace_id: str = "-") -> tuple[bool, str]: """ 真实转人工:发送千牛转接命令,不走AI文本压缩逻辑。 """ if not client.websocket: return False, "websocket_not_connected" acc_id = str(data.get("acc_id", "") or "") from_id = str(data.get("from_id", "") or "") from_name = str(data.get("from_name", from_id) or from_id) acc_type = str(data.get("acc_type", "AliWorkbench") or "AliWorkbench") dispatch_res = await asyncio.to_thread(_dispatch_assign_once) assignee = str(dispatch_res.get("assigned_to", "") or "").strip() or DEFAULT_TRANSFER_ASSIGNEE activity_event( client.logger, "dispatch_assign", trace_id=trace_id, customer_id=from_id or "-", success=bool(dispatch_res.get("success")), assigned_to=assignee, online_count=int(dispatch_res.get("online_count", 0) or 0), reason=str(dispatch_res.get("reason", "") or ""), ) if assignee: cmd = f"正在为你转接人工|[转移会话],{assignee},无原因" target = assignee else: cmd = f"话术|[转移会话],分组{DEFAULT_TRANSFER_GROUP},无原因" target = f"分组{DEFAULT_TRANSFER_GROUP}" msg = { "msg_id": "", "acc_id": acc_id, "msg": cmd, "from_id": from_id, "from_name": from_name, "cy_id": from_id, "acc_type": acc_type, "msg_type": 0, "cy_name": from_name, } await client.send_message(msg) activity_event( client.logger, "transfer_command_sent", trace_id=trace_id, customer_id=from_id or "-", target=target, transfer_msg=(transfer_msg or ""), ) return True, target