Files
group_xinghuo_jinrong/app/model/schemas.py
T
zhanghongyu_0626 b841f68295 feat(visitor): Implement visitor chat functionality and enhance customer service interactions
- Added a new visitor chat API endpoint (`/api/chat/visitor`) to allow unauthenticated users to engage in conversations without requiring customer data.
- Introduced a visitor context dependency to manage visitor interactions seamlessly.
- Enhanced the chat API to support explicit session termination and improved response handling for customer service interactions.
- Updated the database configuration to include Redis client support for caching visitor data.
- Added a new customer note repository to persist user notes independently of the L1 profile slots.

This update significantly improves the customer service experience by enabling visitor interactions and ensuring efficient data handling for both registered and unregistered users.
2026-09-09 18:32:00 +08:00

101 lines
2.6 KiB
Python

"""Pydantic 请求/响应模型、AuthContext 等。"""
from __future__ import annotations
from typing import Any, Literal
from pydantic import BaseModel, Field
AgentType = Literal["customer", "advisor", "analyst", "risk", "visitor"]
TokenType = Literal["customer", "staff", "service", "visitor"]
IntentType = Literal[
"product_consult",
"policy_interpret",
"faq",
"chit_chat",
"save_note",
"reject",
"transfer_human",
"fallback",
"holding_query",
"transaction_query",
"risk_assessment_query",
"suitability_check",
]
class AuthContext(BaseModel):
"""网关校验后注入业务层的身份上下文。"""
sub: str
token_type: TokenType
roles: list[str]
permissions: list[str] = Field(default_factory=list)
tenant_id: str = "default"
trace_id: str
agent_type: AgentType
jti: str
customer_id: str | None = None
def has_role(self, role: str) -> bool:
return role in self.roles
def has_perm(self, perm: str) -> bool:
if perm in self.permissions:
return True
prefix = perm.split(":")[0]
return any(p.startswith(f"{prefix}:") and p.endswith(":*") for p in self.permissions)
class LoginRequest(BaseModel):
actor_id: str = Field(..., description="customer_id 或 staff_id")
token_type: TokenType = "staff"
roles: list[str] | None = Field(default=None, description="开发期可覆盖角色,默认按 actor_id 推断")
class LoginResponseData(BaseModel):
access_token: str
token_type: str = "Bearer"
expires_in: int
sub: str
roles: list[str]
class ChatRequest(BaseModel):
message: str = Field(..., min_length=1, max_length=8000)
session_id: str | None = None
customer_id: str | None = Field(default=None, description="员工 Agent 查询目标客户时使用")
class ChatResponseData(BaseModel):
session_id: str
reply: str
agent_type: AgentType
has_disclaimer: bool = False
intent: IntentType | None = Field(default=None, description="仅 customer 返回")
transfer_to_human: bool = Field(default=False, description="仅 customer 返回")
class ApiResponse(BaseModel):
code: int = 0
message: str = "ok"
data: Any = None
trace_id: str
class VisitorChatRequest(BaseModel):
"""游客对话请求(免认证)。"""
message: str = Field(..., min_length=1, max_length=8000)
session_id: str | None = None
class VisitorChatResponseData(BaseModel):
"""游客对话响应。"""
session_id: str
reply: str
intent: IntentType
has_disclaimer: bool = False
transfer_to_human: bool = False