feat: integrate quality-gated draw flow with online dispatch transfer
Some checks failed
Pre-commit / run (ubuntu-latest) (push) Has been cancelled
Deploy Sphinx documentation to Pages / build_en (ubuntu-latest, 3.10) (push) Has been cancelled
Deploy Sphinx documentation to Pages / build_zh (ubuntu-latest, 3.10) (push) Has been cancelled
Python Unittest Coverage / test (macos-15, 3.10) (push) Has been cancelled
Python Unittest Coverage / test (macos-15, 3.11) (push) Has been cancelled
Python Unittest Coverage / test (macos-15, 3.12) (push) Has been cancelled
Python Unittest Coverage / test (ubuntu-latest, 3.10) (push) Has been cancelled
Python Unittest Coverage / test (ubuntu-latest, 3.11) (push) Has been cancelled
Python Unittest Coverage / test (ubuntu-latest, 3.12) (push) Has been cancelled
Python Unittest Coverage / test (windows-latest, 3.10) (push) Has been cancelled
Python Unittest Coverage / test (windows-latest, 3.11) (push) Has been cancelled
Python Unittest Coverage / test (windows-latest, 3.12) (push) Has been cancelled
Some checks failed
Pre-commit / run (ubuntu-latest) (push) Has been cancelled
Deploy Sphinx documentation to Pages / build_en (ubuntu-latest, 3.10) (push) Has been cancelled
Deploy Sphinx documentation to Pages / build_zh (ubuntu-latest, 3.10) (push) Has been cancelled
Python Unittest Coverage / test (macos-15, 3.10) (push) Has been cancelled
Python Unittest Coverage / test (macos-15, 3.11) (push) Has been cancelled
Python Unittest Coverage / test (macos-15, 3.12) (push) Has been cancelled
Python Unittest Coverage / test (ubuntu-latest, 3.10) (push) Has been cancelled
Python Unittest Coverage / test (ubuntu-latest, 3.11) (push) Has been cancelled
Python Unittest Coverage / test (ubuntu-latest, 3.12) (push) Has been cancelled
Python Unittest Coverage / test (windows-latest, 3.10) (push) Has been cancelled
Python Unittest Coverage / test (windows-latest, 3.11) (push) Has been cancelled
Python Unittest Coverage / test (windows-latest, 3.12) (push) Has been cancelled
This commit is contained in:
91
qingjian_cs/app/transfer_flow.py
Normal file
91
qingjian_cs/app/transfer_flow.py
Normal file
@@ -0,0 +1,91 @@
|
||||
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
|
||||
Reference in New Issue
Block a user