WIP-CHECKPOINT[auth-refactor]: 固化工程师崩溃前部分成果 + 同树其他未提交WIP(仅源码,不含密钥/二进制)-- 待重激活工程师续作
This commit is contained in:
@@ -0,0 +1,246 @@
|
||||
# =============================================================================
|
||||
# 企微IT智能服务台 — 阶段5 自动化闭环 Schema
|
||||
# =============================================================================
|
||||
# 说明:定义自动化会话相关接口的 Pydantic 请求/响应模型,以及 ORM → dict
|
||||
# 序列化辅助函数。所有响应沿用项目 {code, data, message} 约定,
|
||||
# 此处只描述 data 结构。
|
||||
# =============================================================================
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import datetime
|
||||
from typing import Any, Dict, List, Optional
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# 请求模型
|
||||
# --------------------------------------------------------------------------
|
||||
class CreateSessionRequest(BaseModel):
|
||||
"""创建自动化会话请求。"""
|
||||
|
||||
conversation_id: Optional[str] = Field(None, description="关联工单ID(弱关联)")
|
||||
employee_id: str = Field(..., description="发起员工企微 UserID")
|
||||
description: str = Field(..., description="员工诉求/原始消息")
|
||||
mode: str = Field("real_exec", description="执行模式:plan_only / real_exec")
|
||||
|
||||
|
||||
class ApprovalDecisionRequest(BaseModel):
|
||||
"""坐席审批决策请求。"""
|
||||
|
||||
decision: str = Field(..., description="approve / reject")
|
||||
note: Optional[str] = Field(None, description="审批意见")
|
||||
|
||||
|
||||
class ConfirmRequest(BaseModel):
|
||||
"""员工 H5 二次确认请求。"""
|
||||
|
||||
confirmed: bool = Field(..., description="是否确认执行")
|
||||
note: Optional[str] = Field(None, description="备注")
|
||||
|
||||
|
||||
class TakeoverRequest(BaseModel):
|
||||
"""转人工接管请求。"""
|
||||
|
||||
agent_id: str = Field(..., description="接管坐席ID")
|
||||
note: Optional[str] = Field(None, description="接管说明")
|
||||
|
||||
|
||||
class ResolveFeedbackRequest(BaseModel):
|
||||
"""处置结果反馈(员工是否满意)。"""
|
||||
|
||||
satisfied: bool = Field(True, description="是否满意")
|
||||
note: Optional[str] = Field(None, description="反馈备注")
|
||||
|
||||
|
||||
class ScenarioConfigUpdate(BaseModel):
|
||||
"""场景配置更新请求(管理端)。"""
|
||||
|
||||
name: Optional[str] = None
|
||||
description: Optional[str] = None
|
||||
enabled: Optional[bool] = None
|
||||
trigger_conditions: Optional[dict] = None
|
||||
actions: Optional[list] = None
|
||||
approval_strategy: Optional[dict] = None
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# 响应模型
|
||||
# --------------------------------------------------------------------------
|
||||
class IntentResult(BaseModel):
|
||||
"""意图识别结果。"""
|
||||
|
||||
scenario_key: Optional[str] = None
|
||||
confidence: float = 0.0
|
||||
raw: str = ""
|
||||
error: str = ""
|
||||
|
||||
|
||||
class ActionResponse(BaseModel):
|
||||
"""处置动作响应。"""
|
||||
|
||||
id: str
|
||||
session_id: str
|
||||
action_index: int
|
||||
action_type: str
|
||||
adapter: str
|
||||
risk_level: str
|
||||
title: str
|
||||
description: str
|
||||
status: str
|
||||
payload: Optional[dict] = None
|
||||
result: Optional[dict] = None
|
||||
error: Optional[str] = None
|
||||
approved_by: Optional[str] = None
|
||||
approved_at: Optional[str] = None
|
||||
|
||||
|
||||
class ApprovalTicketResponse(BaseModel):
|
||||
"""审批单响应。"""
|
||||
|
||||
id: str
|
||||
action_id: str
|
||||
session_id: str
|
||||
approver_id: Optional[str] = None
|
||||
channel: str
|
||||
status: str
|
||||
reason: Optional[str] = None
|
||||
decision_note: Optional[str] = None
|
||||
decided_at: Optional[str] = None
|
||||
|
||||
|
||||
class SessionResponse(BaseModel):
|
||||
"""自动化会话响应。"""
|
||||
|
||||
id: str
|
||||
conversation_id: Optional[str] = None
|
||||
employee_id: str
|
||||
agent_id: Optional[str] = None
|
||||
scenario_key: Optional[str] = None
|
||||
status: str
|
||||
mode: str
|
||||
confidence: float
|
||||
title: str
|
||||
intent: Optional[dict] = None
|
||||
current_action_id: Optional[str] = None
|
||||
auto_close_at: Optional[str] = None
|
||||
resolved_at: Optional[str] = None
|
||||
closed_by: Optional[str] = None
|
||||
meta: Optional[dict] = None
|
||||
actions: List[ActionResponse] = Field(default_factory=list)
|
||||
approval: Optional[ApprovalTicketResponse] = None
|
||||
created_at: Optional[str] = None
|
||||
updated_at: Optional[str] = None
|
||||
|
||||
|
||||
class ScenarioConfigResponse(BaseModel):
|
||||
"""场景配置响应。"""
|
||||
|
||||
id: str
|
||||
scenario_key: str
|
||||
name: str
|
||||
description: str
|
||||
enabled: bool
|
||||
trigger_conditions: Optional[dict] = None
|
||||
actions: Optional[list] = None
|
||||
approval_strategy: Optional[dict] = None
|
||||
current_version_id: Optional[str] = None
|
||||
|
||||
|
||||
class RuleVersionResponse(BaseModel):
|
||||
"""规则版本响应。"""
|
||||
|
||||
id: str
|
||||
scenario_key: str
|
||||
version: int
|
||||
content: Optional[dict] = None
|
||||
status: str
|
||||
canary_percent: int
|
||||
created_by: Optional[str] = None
|
||||
remark: str
|
||||
created_at: Optional[str] = None
|
||||
|
||||
|
||||
class AutoMetricsResponse(BaseModel):
|
||||
"""自动化看板指标响应。"""
|
||||
|
||||
total_sessions: int = 0
|
||||
resolved_sessions: int = 0
|
||||
handoff_sessions: int = 0
|
||||
error_sessions: int = 0
|
||||
auto_executed_actions: int = 0
|
||||
approval_required_actions: int = 0
|
||||
by_scenario: Dict[str, int] = Field(default_factory=dict)
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# 序列化辅助
|
||||
# --------------------------------------------------------------------------
|
||||
def _iso(dt: Optional[datetime]) -> Optional[str]:
|
||||
"""将 datetime 转为 ISO 字符串(None 透传)。"""
|
||||
return dt.isoformat() if dt else None
|
||||
|
||||
|
||||
def serialize_action(action: Any) -> ActionResponse:
|
||||
"""将 AutoAction ORM 对象序列化为响应模型。"""
|
||||
return ActionResponse(
|
||||
id=action.id,
|
||||
session_id=action.session_id,
|
||||
action_index=action.action_index,
|
||||
action_type=action.action_type,
|
||||
adapter=action.adapter,
|
||||
risk_level=action.risk_level,
|
||||
title=action.title,
|
||||
description=action.description,
|
||||
status=action.status,
|
||||
payload=action.payload,
|
||||
result=action.result,
|
||||
error=action.error,
|
||||
approved_by=action.approved_by,
|
||||
approved_at=_iso(action.approved_at),
|
||||
)
|
||||
|
||||
|
||||
def serialize_approval(ticket: Any) -> ApprovalTicketResponse:
|
||||
"""将 ApprovalTicket ORM 对象序列化为响应模型。"""
|
||||
return ApprovalTicketResponse(
|
||||
id=ticket.id,
|
||||
action_id=ticket.action_id,
|
||||
session_id=ticket.session_id,
|
||||
approver_id=ticket.approver_id,
|
||||
channel=ticket.channel,
|
||||
status=ticket.status,
|
||||
reason=ticket.reason,
|
||||
decision_note=ticket.decision_note,
|
||||
decided_at=_iso(ticket.decided_at),
|
||||
)
|
||||
|
||||
|
||||
def serialize_session(
|
||||
session: Any,
|
||||
actions: Optional[List[Any]] = None,
|
||||
ticket: Optional[Any] = None,
|
||||
) -> SessionResponse:
|
||||
"""将 AutoSession ORM 对象序列化为响应模型。"""
|
||||
return SessionResponse(
|
||||
id=session.id,
|
||||
conversation_id=session.conversation_id,
|
||||
employee_id=session.employee_id,
|
||||
agent_id=session.agent_id,
|
||||
scenario_key=session.scenario_key,
|
||||
status=session.status,
|
||||
mode=session.mode,
|
||||
confidence=session.confidence,
|
||||
title=session.title,
|
||||
intent=session.intent,
|
||||
current_action_id=session.current_action_id,
|
||||
auto_close_at=_iso(session.auto_close_at),
|
||||
resolved_at=_iso(session.resolved_at),
|
||||
closed_by=session.closed_by,
|
||||
meta=session.meta,
|
||||
actions=[serialize_action(a) for a in (actions or [])],
|
||||
approval=serialize_approval(ticket) if ticket else None,
|
||||
created_at=_iso(session.created_at),
|
||||
updated_at=_iso(session.updated_at),
|
||||
)
|
||||
Reference in New Issue
Block a user